From 8773a4ec2891f1ec7bdaf5453eb522ab697606ef Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 29 Apr 2019 08:21:54 +0900 Subject: Install react --- package-lock.json | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 4 ++ 2 files changed, 174 insertions(+) diff --git a/package-lock.json b/package-lock.json index 1e9353e..45497fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -116,6 +116,23 @@ "integrity": "sha512-ATz6yX/L8LEnC3dtLQnIx4ydcPxhLcoy9Vl6re00zb2w5lG6itY6Vhnr1KFRPq/FHNsgl/gh2mjNN20f9iJTTA==", "dev": true }, + "@babel/runtime": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.4.tgz", + "integrity": "sha512-w0+uT71b6Yi7i5SE0co4NioIpSYS6lLiXvCzWzGSKvpK5vdQtCbICHMj+gbAKAOtxiV6HsVh/MBdaF9EQ6faSg==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==", + "dev": true + } + } + }, "@babel/template": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", @@ -981,6 +998,12 @@ "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", "dev": true }, + "babel-plugin-syntax-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", + "dev": true + }, "babel-plugin-syntax-jsx": { "version": "6.18.0", "resolved": "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", @@ -1057,6 +1080,16 @@ "babel-runtime": "^6.22.0" } }, + "babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "dev": true, + "requires": { + "babel-plugin-syntax-flow": "^6.18.0", + "babel-runtime": "^6.22.0" + } + }, "babel-plugin-transform-object-rest-spread": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", @@ -1067,6 +1100,15 @@ "babel-runtime": "^6.26.0" } }, + "babel-plugin-transform-react-display-name": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, "babel-plugin-transform-react-jsx": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", @@ -1078,6 +1120,26 @@ "babel-runtime": "^6.22.0" } }, + "babel-plugin-transform-react-jsx-self": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", + "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx-source": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", + "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, "babel-polyfill": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", @@ -1097,6 +1159,15 @@ } } }, + "babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "^6.22.0" + } + }, "babel-preset-preact": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/babel-preset-preact/-/babel-preset-preact-1.1.0.tgz", @@ -1107,6 +1178,20 @@ "babel-plugin-transform-react-jsx": "^6.0.2" } }, + "babel-preset-react": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", + "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.3.13", + "babel-plugin-transform-react-display-name": "^6.23.0", + "babel-plugin-transform-react-jsx": "^6.24.1", + "babel-plugin-transform-react-jsx-self": "^6.22.0", + "babel-plugin-transform-react-jsx-source": "^6.22.0", + "babel-preset-flow": "^6.23.0" + } + }, "babel-preset-stage-2": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", @@ -4865,6 +4950,15 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hoist-non-react-statics": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "dev": true, + "requires": { + "react-is": "^16.7.0" + } + }, "home-or-tmp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", @@ -8594,6 +8688,72 @@ "unpipe": "1.0.0" } }, + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-dom": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", + "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==", + "dev": true + }, + "react-redux": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.0.3.tgz", + "integrity": "sha512-vYZA7ftOYlDk3NetitsI7fLjryt/widNl1SLXYvFenIpm7vjb4ryK0EeFrgn62usg5fYkyIAWNUPKnwWPevKLg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.3", + "hoist-non-react-statics": "^3.3.0", + "invariant": "^2.2.4", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^16.8.6" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -9080,6 +9240,16 @@ "semver": "^5.5.0" } }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", diff --git a/package.json b/package.json index 7c758a2..ea3291c 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "babel-eslint": "^10.0.1", "babel-loader": "^7.1.5", "babel-preset-preact": "^1.1.0", + "babel-preset-react": "^6.24.1", "babel-preset-stage-2": "^6.24.1", "chai": "^4.2.0", "css-loader": "^2.1.1", @@ -44,6 +45,9 @@ "node-sass": "^4.12.0", "preact": "^8.4.2", "preact-redux": "^2.0.3", + "react": "^16.8.6", + "react-dom": "^16.8.6", + "react-redux": "^7.0.3", "redux": "^4.0.1", "redux-promise": "^0.6.0", "sass-loader": "^7.1.0", -- cgit v1.2.3 From 55f15c9350cc531324e6182895f494eeb8174bc6 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 29 Apr 2019 09:13:59 +0900 Subject: Move to react --- src/console/components/console.jsx | 34 ++++++++++++---------- src/console/components/console/completion.jsx | 4 +-- src/console/components/console/input.jsx | 4 +-- src/console/components/console/message.jsx | 2 -- src/console/index.html | 4 ++- src/console/index.jsx | 12 ++++---- src/settings/components/form/blacklist-form.jsx | 4 +-- src/settings/components/form/keymaps-form.jsx | 4 +-- src/settings/components/form/properties-form.jsx | 4 +-- src/settings/components/form/search-form.jsx | 4 +-- src/settings/components/index.jsx | 8 ++--- src/settings/components/ui/add-button.jsx | 4 +-- src/settings/components/ui/delete-button.jsx | 4 +-- src/settings/components/ui/input.jsx | 4 +-- src/settings/index.jsx | 4 +-- .../console/components/console/completion.test.jsx | 2 +- .../components/form/blacklist-form.test.jsx | 2 +- .../settings/components/form/keymaps-form.test.jsx | 2 +- .../components/form/properties-form.test.jsx | 2 +- .../components/form/search-engine-form.test.jsx | 2 +- test/settings/components/ui/input.test.jsx | 2 +- webpack.config.js | 2 +- 22 files changed, 58 insertions(+), 56 deletions(-) diff --git a/src/console/components/console.jsx b/src/console/components/console.jsx index 7994f78..b792088 100644 --- a/src/console/components/console.jsx +++ b/src/console/components/console.jsx @@ -1,6 +1,6 @@ import './console.scss'; -import { connect } from 'preact-redux'; -import { Component, h } from 'preact'; +import { connect } from 'react-redux'; +import React from 'react'; import Input from './console/input'; import Completion from './console/completion'; import Message from './console/message'; @@ -8,10 +8,10 @@ import * as consoleActions from '../../console/actions/console'; const COMPLETION_MAX_ITEMS = 33; -class ConsoleComponent extends Component { +class ConsoleComponent extends React.Component { onBlur() { if (this.props.mode === 'command' || this.props.mode === 'find') { - return this.context.store.dispatch(consoleActions.hideCommand()); + return this.props.dispatch(consoleActions.hideCommand()); } } @@ -21,45 +21,45 @@ class ConsoleComponent extends Component { let value = e.target.value; if (this.props.mode === 'command') { - return this.context.store.dispatch(consoleActions.enterCommand(value)); + return this.props.dispatch(consoleActions.enterCommand(value)); } else if (this.props.mode === 'find') { - return this.context.store.dispatch(consoleActions.enterFind(value)); + return this.props.dispatch(consoleActions.enterFind(value)); } } selectNext(e) { - this.context.store.dispatch(consoleActions.completionNext()); + this.props.dispatch(consoleActions.completionNext()); e.stopPropagation(); e.preventDefault(); } selectPrev(e) { - this.context.store.dispatch(consoleActions.completionPrev()); + this.props.dispatch(consoleActions.completionPrev()); e.stopPropagation(); e.preventDefault(); } onKeyDown(e) { if (e.keyCode === KeyboardEvent.DOM_VK_ESCAPE && e.ctrlKey) { - this.context.store.dispatch(consoleActions.hideCommand()); + this.props.dispatch(consoleActions.hideCommand()); } switch (e.keyCode) { case KeyboardEvent.DOM_VK_ESCAPE: - return this.context.store.dispatch(consoleActions.hideCommand()); + return this.props.dispatch(consoleActions.hideCommand()); case KeyboardEvent.DOM_VK_RETURN: return this.doEnter(e); case KeyboardEvent.DOM_VK_TAB: if (e.shiftKey) { - this.context.store.dispatch(consoleActions.completionPrev()); + this.props.dispatch(consoleActions.completionPrev()); } else { - this.context.store.dispatch(consoleActions.completionNext()); + this.props.dispatch(consoleActions.completionNext()); } e.stopPropagation(); e.preventDefault(); break; case KeyboardEvent.DOM_VK_OPEN_BRACKET: if (e.ctrlKey) { - return this.context.store.dispatch(consoleActions.hideCommand()); + return this.props.dispatch(consoleActions.hideCommand()); } break; case KeyboardEvent.DOM_VK_M: @@ -82,9 +82,9 @@ class ConsoleComponent extends Component { onInput(e) { let text = e.target.value; - this.context.store.dispatch(consoleActions.setConsoleText(text)); + this.props.dispatch(consoleActions.setConsoleText(text)); if (this.props.mode === 'command') { - this.context.store.dispatch(consoleActions.getCompletions(text)); + this.props.dispatch(consoleActions.getCompletions(text)); } } @@ -94,7 +94,7 @@ class ConsoleComponent extends Component { return; } if (prevProps.mode !== 'command' && this.props.mode === 'command') { - this.context.store.dispatch( + this.props.dispatch( consoleActions.getCompletions(this.props.consoleText)); this.focus(); } else if (prevProps.mode !== 'find' && this.props.mode === 'find') { @@ -126,6 +126,8 @@ class ConsoleComponent extends Component { return { this.props.messageText } ; + default: + return null; } } diff --git a/src/console/components/console/completion.jsx b/src/console/components/console/completion.jsx index d836cec..5d248a0 100644 --- a/src/console/components/console/completion.jsx +++ b/src/console/components/console/completion.jsx @@ -1,4 +1,4 @@ -import { Component, h } from 'preact'; +import React from 'react'; const CompletionTitle = (props) => { return
  • {props.title}
  • ; @@ -23,7 +23,7 @@ const CompletionItem = (props) => { }; -class CompletionComponent extends Component { +class CompletionComponent extends React.Component { constructor() { super(); this.state = { viewOffset: 0, select: -1 }; diff --git a/src/console/components/console/input.jsx b/src/console/components/console/input.jsx index d59e6e7..3ac075e 100644 --- a/src/console/components/console/input.jsx +++ b/src/console/components/console/input.jsx @@ -1,6 +1,6 @@ -import { Component, h } from 'preact'; +import React from 'react'; -export default class InputComponent extends Component { +export default class InputComponent extends React.Component { focus() { this.input.focus(); } diff --git a/src/console/components/console/message.jsx b/src/console/components/console/message.jsx index 5b60af4..0370f01 100644 --- a/src/console/components/console/message.jsx +++ b/src/console/components/console/message.jsx @@ -1,5 +1,3 @@ -import { h } from 'preact'; - export default function Message(props) { switch (props.mode) { case 'error': diff --git a/src/console/index.html b/src/console/index.html index 5c1e99c..73e1e23 100644 --- a/src/console/index.html +++ b/src/console/index.html @@ -5,5 +5,7 @@ VimVixen console - + +
    + diff --git a/src/console/index.jsx b/src/console/index.jsx index dfd323e..0d0a8b9 100644 --- a/src/console/index.jsx +++ b/src/console/index.jsx @@ -3,11 +3,10 @@ import reducers from 'console/reducers'; import { createStore, applyMiddleware } from 'redux'; import promise from 'redux-promise'; import * as consoleActions from 'console/actions/console'; - -import { Provider } from 'preact-redux'; +import { Provider } from 'react-redux'; import Console from './components/console'; - -import { render, h } from 'preact'; +import React from 'react'; +import ReactDOM from 'react-dom'; const store = createStore( reducers, @@ -15,11 +14,12 @@ const store = createStore( ); window.addEventListener('load', () => { - render( + let wrapper = document.getElementById('vimvixen-console'); + ReactDOM.render( , - document.body); + wrapper); }); const onMessage = (message) => { diff --git a/src/settings/components/form/blacklist-form.jsx b/src/settings/components/form/blacklist-form.jsx index 7ae9652..492c3af 100644 --- a/src/settings/components/form/blacklist-form.jsx +++ b/src/settings/components/form/blacklist-form.jsx @@ -1,9 +1,9 @@ import './blacklist-form.scss'; import AddButton from '../ui/add-button'; import DeleteButton from '../ui/delete-button'; -import { h, Component } from 'preact'; +import React from 'react'; -class BlacklistForm extends Component { +class BlacklistForm extends React.Component { render() { let value = this.props.value; diff --git a/src/settings/components/form/keymaps-form.jsx b/src/settings/components/form/keymaps-form.jsx index ca51c96..8c0a83f 100644 --- a/src/settings/components/form/keymaps-form.jsx +++ b/src/settings/components/form/keymaps-form.jsx @@ -1,5 +1,5 @@ import './keymaps-form.scss'; -import { h, Component } from 'preact'; +import React from 'react'; import Input from '../ui/input'; const KeyMapFields = [ @@ -72,7 +72,7 @@ const KeyMapFields = [ const AllowdOps = [].concat(...KeyMapFields.map(group => group.map(e => e[0]))); -class KeymapsForm extends Component { +class KeymapsForm extends React.Component { render() { let values = this.props.value; diff --git a/src/settings/components/form/properties-form.jsx b/src/settings/components/form/properties-form.jsx index ceb79d7..7d591d5 100644 --- a/src/settings/components/form/properties-form.jsx +++ b/src/settings/components/form/properties-form.jsx @@ -1,7 +1,7 @@ import './properties-form.scss'; -import { h, Component } from 'preact'; +import React from 'react'; -class PropertiesForm extends Component { +class PropertiesForm extends React.Component { render() { let types = this.props.types; diff --git a/src/settings/components/form/search-form.jsx b/src/settings/components/form/search-form.jsx index 2d5f01b..81204f3 100644 --- a/src/settings/components/form/search-form.jsx +++ b/src/settings/components/form/search-form.jsx @@ -1,9 +1,9 @@ import './search-form.scss'; -import { h, Component } from 'preact'; +import React from 'react'; import AddButton from '../ui/add-button'; import DeleteButton from '../ui/delete-button'; -class SearchForm extends Component { +class SearchForm extends React.Component { render() { let value = this.props.value; diff --git a/src/settings/components/index.jsx b/src/settings/components/index.jsx index 9633359..9dae25e 100644 --- a/src/settings/components/index.jsx +++ b/src/settings/components/index.jsx @@ -1,6 +1,6 @@ import './site.scss'; -import { h, Component } from 'preact'; -import { connect } from 'preact-redux'; +import React from 'react'; +import { connect } from 'react-redux'; import Input from './ui/input'; import SearchForm from './form/search-form'; import KeymapsForm from './form/keymaps-form'; @@ -13,7 +13,7 @@ const DO_YOU_WANT_TO_CONTINUE = 'Some settings in JSON can be lost when migrating. ' + 'Do you want to continue?'; -class SettingsComponent extends Component { +class SettingsComponent extends React.Component { componentDidMount() { this.props.dispatch(settingActions.load()); } @@ -136,7 +136,7 @@ class SettingsComponent extends Component { this.props.dispatch(settingActions.switchToForm(this.props.json)); } - let settings = this.context.store.getState(); + let settings = this.props.getState(); this.props.dispatch(settingActions.save(settings)); } } diff --git a/src/settings/components/ui/add-button.jsx b/src/settings/components/ui/add-button.jsx index 79292d8..031d28b 100644 --- a/src/settings/components/ui/add-button.jsx +++ b/src/settings/components/ui/add-button.jsx @@ -1,7 +1,7 @@ import './add-button.scss'; -import { h, Component } from 'preact'; +import React from 'react'; -class AddButton extends Component { +class AddButton extends React.Component { render() { return { diff --git a/test/settings/components/form/blacklist-form.test.jsx b/test/settings/components/form/blacklist-form.test.jsx index 1c46943..40067d0 100644 --- a/test/settings/components/form/blacklist-form.test.jsx +++ b/test/settings/components/form/blacklist-form.test.jsx @@ -1,4 +1,4 @@ -import { h, render } from 'preact'; +import { render } from 'react'; import BlacklistForm from 'settings/components/form/blacklist-form' describe("settings/form/BlacklistForm", () => { diff --git a/test/settings/components/form/keymaps-form.test.jsx b/test/settings/components/form/keymaps-form.test.jsx index 55edf8c..79d8d20 100644 --- a/test/settings/components/form/keymaps-form.test.jsx +++ b/test/settings/components/form/keymaps-form.test.jsx @@ -1,4 +1,4 @@ -import { h, render } from 'preact'; +import { render } from 'react'; import KeymapsForm from 'settings/components/form/keymaps-form' describe("settings/form/KeymapsForm", () => { diff --git a/test/settings/components/form/properties-form.test.jsx b/test/settings/components/form/properties-form.test.jsx index 0efe382..171dcb6 100644 --- a/test/settings/components/form/properties-form.test.jsx +++ b/test/settings/components/form/properties-form.test.jsx @@ -1,4 +1,4 @@ -import { h, render } from 'preact'; +import { render } from 'react'; import PropertiesForm from 'settings/components/form/properties-form' describe("settings/form/PropertiesForm", () => { diff --git a/test/settings/components/form/search-engine-form.test.jsx b/test/settings/components/form/search-engine-form.test.jsx index c52419d..d1cbb30 100644 --- a/test/settings/components/form/search-engine-form.test.jsx +++ b/test/settings/components/form/search-engine-form.test.jsx @@ -1,4 +1,4 @@ -import { h, render } from 'preact'; +import { render } from 'react'; import SearchForm from 'settings/components/form/search-form' describe("settings/form/SearchForm", () => { diff --git a/test/settings/components/ui/input.test.jsx b/test/settings/components/ui/input.test.jsx index 0711bba..db12bf8 100644 --- a/test/settings/components/ui/input.test.jsx +++ b/test/settings/components/ui/input.test.jsx @@ -1,4 +1,4 @@ -import { h, render } from 'preact'; +import { render } from 'react'; import Input from 'settings/components/ui/input' describe("settings/ui/Input", () => { diff --git a/webpack.config.js b/webpack.config.js index 90fd526..9694fd5 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -24,7 +24,7 @@ config = { exclude: /node_modules/, loader: 'babel-loader', query: { - presets: ['preact', 'stage-2'] + presets: ['react', 'stage-2'] } }, { -- cgit v1.2.3 From 46228c6b184a662b3b8398b6d5604c177f0c158e Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 29 Apr 2019 09:15:58 +0900 Subject: Uninstall preact --- package-lock.json | 22 ---------------------- package.json | 3 --- src/console/components/console/message.jsx | 2 ++ 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 45497fa..8a03588 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1168,16 +1168,6 @@ "babel-plugin-transform-flow-strip-types": "^6.22.0" } }, - "babel-preset-preact": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-preact/-/babel-preset-preact-1.1.0.tgz", - "integrity": "sha1-NaxlWnOkm4Q4FjzgU4Fld+GYCGE=", - "dev": true, - "requires": { - "babel-plugin-syntax-jsx": "^6.0.2", - "babel-plugin-transform-react-jsx": "^6.0.2" - } - }, "babel-preset-react": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", @@ -8443,18 +8433,6 @@ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", "dev": true }, - "preact": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-8.4.2.tgz", - "integrity": "sha512-TsINETWiisfB6RTk0wh3/mvxbGRvx+ljeBccZ4Z6MPFKgu/KFGyf2Bmw3Z/jlXhL5JlNKY6QAbA9PVyzIy9//A==", - "dev": true - }, - "preact-redux": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/preact-redux/-/preact-redux-2.0.3.tgz", - "integrity": "sha1-lgpTXDImQ801mY8z8MLme8Hn6qs=", - "dev": true - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", diff --git a/package.json b/package.json index ea3291c..2ab1feb 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "babel-cli": "^6.26.0", "babel-eslint": "^10.0.1", "babel-loader": "^7.1.5", - "babel-preset-preact": "^1.1.0", "babel-preset-react": "^6.24.1", "babel-preset-stage-2": "^6.24.1", "chai": "^4.2.0", @@ -43,8 +42,6 @@ "lanthan": "git+https://github.com/ueokande/lanthan.git#master", "mocha": "^6.1.4", "node-sass": "^4.12.0", - "preact": "^8.4.2", - "preact-redux": "^2.0.3", "react": "^16.8.6", "react-dom": "^16.8.6", "react-redux": "^7.0.3", diff --git a/src/console/components/console/message.jsx b/src/console/components/console/message.jsx index 0370f01..6c8297f 100644 --- a/src/console/components/console/message.jsx +++ b/src/console/components/console/message.jsx @@ -1,3 +1,5 @@ +import React from 'react'; + export default function Message(props) { switch (props.mode) { case 'error': -- cgit v1.2.3 From 25111f9de4b7959cdd97b51bfdd2f1c2a7124e48 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 29 Apr 2019 10:31:58 +0900 Subject: Declare component prop types on console --- src/console/components/Console.jsx | 152 +++++++++++++++++++++ src/console/components/console.jsx | 141 ------------------- src/console/components/console/Completion.jsx | 86 ++++++++++++ src/console/components/console/CompletionItem.jsx | 28 ++++ src/console/components/console/CompletionTitle.jsx | 14 ++ src/console/components/console/Input.jsx | 43 ++++++ src/console/components/console/Message.jsx | 25 ++++ src/console/components/console/completion.jsx | 89 ------------ src/console/components/console/input.jsx | 32 ----- src/console/components/console/message.jsx | 18 --- src/console/index.jsx | 2 +- 11 files changed, 349 insertions(+), 281 deletions(-) create mode 100644 src/console/components/Console.jsx delete mode 100644 src/console/components/console.jsx create mode 100644 src/console/components/console/Completion.jsx create mode 100644 src/console/components/console/CompletionItem.jsx create mode 100644 src/console/components/console/CompletionTitle.jsx create mode 100644 src/console/components/console/Input.jsx create mode 100644 src/console/components/console/Message.jsx delete mode 100644 src/console/components/console/completion.jsx delete mode 100644 src/console/components/console/input.jsx delete mode 100644 src/console/components/console/message.jsx diff --git a/src/console/components/Console.jsx b/src/console/components/Console.jsx new file mode 100644 index 0000000..6a9cebd --- /dev/null +++ b/src/console/components/Console.jsx @@ -0,0 +1,152 @@ +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; + } + } + + onInput(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)} + onInput={this.onInput.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, + onBlur: PropTypes.func, + onKeyDown: PropTypes.func, + onInput: PropTypes.func, + 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.jsx b/src/console/components/console.jsx deleted file mode 100644 index b792088..0000000 --- a/src/console/components/console.jsx +++ /dev/null @@ -1,141 +0,0 @@ -import './console.scss'; -import { connect } from 'react-redux'; -import React from 'react'; -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 ConsoleComponent 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; - } - } - - onInput(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)} - onInput={this.onInput.bind(this)} - value={this.props.consoleText} - /> -
    ; - case 'info': - case 'error': - return - { this.props.messageText } - ; - default: - return null; - } - } - - focus() { - window.focus(); - this.input.focus(); - } -} - -const mapStateToProps = state => state; -export default connect(mapStateToProps)(ConsoleComponent); diff --git a/src/console/components/console/Completion.jsx b/src/console/components/console/Completion.jsx new file mode 100644 index 0000000..5477cb6 --- /dev/null +++ b/src/console/components/console/Completion.jsx @@ -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 ( +
      + { eles } +
    + ); + } +} + +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 new file mode 100644 index 0000000..3dc552b --- /dev/null +++ b/src/console/components/console/CompletionItem.jsx @@ -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 new file mode 100644 index 0000000..4fcba3f --- /dev/null +++ b/src/console/components/console/CompletionTitle.jsx @@ -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 new file mode 100644 index 0000000..c85d252 --- /dev/null +++ b/src/console/components/console/Input.jsx @@ -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} + onInput={this.props.onInput} + value={this.props.value} + /> +
    + ); + } +} + +Input.propTypes = { + mode: PropTypes.string, + value: PropTypes.string, + onBlur: PropTypes.func, + onKeyDown: PropTypes.func, + onInput: PropTypes.func, +}; + +export default Input; diff --git a/src/console/components/console/Message.jsx b/src/console/components/console/Message.jsx new file mode 100644 index 0000000..dd96248 --- /dev/null +++ b/src/console/components/console/Message.jsx @@ -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; diff --git a/src/console/components/console/completion.jsx b/src/console/components/console/completion.jsx deleted file mode 100644 index 5d248a0..0000000 --- a/src/console/components/console/completion.jsx +++ /dev/null @@ -1,89 +0,0 @@ -import React from 'react'; - -const CompletionTitle = (props) => { - return
  • {props.title}
  • ; -}; - -const CompletionItem = (props) => { - let className = 'vimvixen-console-completion-item'; - if (props.highlight) { - className += ' vimvixen-completion-selected'; - } - return
  • - {props.caption} - {props.url} -
  • ; -}; - - -class CompletionComponent 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 ( -
      - { eles } -
    - ); - } -} - -export default CompletionComponent; diff --git a/src/console/components/console/input.jsx b/src/console/components/console/input.jsx deleted file mode 100644 index 3ac075e..0000000 --- a/src/console/components/console/input.jsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; - -export default class InputComponent 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} - onInput={this.props.onInput} - value={this.props.value} - /> -
    - ); - } -} diff --git a/src/console/components/console/message.jsx b/src/console/components/console/message.jsx deleted file mode 100644 index 6c8297f..0000000 --- a/src/console/components/console/message.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; - -export default function Message(props) { - switch (props.mode) { - case 'error': - return ( -

    - { props.children } -

    - ); - case 'info': - return ( -

    - { props.children } -

    - ); - } -} diff --git a/src/console/index.jsx b/src/console/index.jsx index 0d0a8b9..3190a9a 100644 --- a/src/console/index.jsx +++ b/src/console/index.jsx @@ -4,7 +4,7 @@ import { createStore, applyMiddleware } from 'redux'; import promise from 'redux-promise'; import * as consoleActions from 'console/actions/console'; import { Provider } from 'react-redux'; -import Console from './components/console'; +import Console from './components/Console'; import React from 'react'; import ReactDOM from 'react-dom'; -- cgit v1.2.3 From be900aa25ca205c467dcbbab9c284ef680441996 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 29 Apr 2019 15:27:23 +0900 Subject: Clean settings components --- src/settings/actions/setting.js | 5 +- src/settings/components/form/BlacklistForm.jsx | 52 ++++++++++ src/settings/components/form/BlacklistForm.scss | 9 ++ src/settings/components/form/KeymapsForm.jsx | 47 +++++++++ src/settings/components/form/KeymapsForm.scss | 11 ++ src/settings/components/form/PropertiesForm.jsx | 60 +++++++++++ src/settings/components/form/PropertiesForm.scss | 12 +++ src/settings/components/form/SearchForm.jsx | 78 ++++++++++++++ src/settings/components/form/SearchForm.scss | 28 +++++ src/settings/components/form/blacklist-form.jsx | 52 ---------- src/settings/components/form/blacklist-form.scss | 9 -- src/settings/components/form/keymaps-form.jsx | 118 ---------------------- src/settings/components/form/keymaps-form.scss | 11 -- src/settings/components/form/properties-form.jsx | 60 ----------- src/settings/components/form/properties-form.scss | 12 --- src/settings/components/form/search-form.jsx | 78 -------------- src/settings/components/form/search-form.scss | 28 ----- src/settings/components/index.jsx | 12 +-- src/settings/components/ui/AddButton.jsx | 12 +++ src/settings/components/ui/AddButton.scss | 13 +++ src/settings/components/ui/DeleteButton.jsx | 12 +++ src/settings/components/ui/DeleteButton.scss | 13 +++ src/settings/components/ui/Input.jsx | 52 ++++++++++ src/settings/components/ui/Input.scss | 29 ++++++ src/settings/components/ui/add-button.jsx | 12 --- src/settings/components/ui/add-button.scss | 13 --- src/settings/components/ui/delete-button.jsx | 12 --- src/settings/components/ui/delete-button.scss | 13 --- src/settings/components/ui/input.jsx | 52 ---------- src/settings/components/ui/input.scss | 29 ------ src/settings/index.jsx | 7 +- src/settings/keymaps.js | 74 ++++++++++++++ 32 files changed, 514 insertions(+), 511 deletions(-) create mode 100644 src/settings/components/form/BlacklistForm.jsx create mode 100644 src/settings/components/form/BlacklistForm.scss create mode 100644 src/settings/components/form/KeymapsForm.jsx create mode 100644 src/settings/components/form/KeymapsForm.scss create mode 100644 src/settings/components/form/PropertiesForm.jsx create mode 100644 src/settings/components/form/PropertiesForm.scss create mode 100644 src/settings/components/form/SearchForm.jsx create mode 100644 src/settings/components/form/SearchForm.scss delete mode 100644 src/settings/components/form/blacklist-form.jsx delete mode 100644 src/settings/components/form/blacklist-form.scss delete mode 100644 src/settings/components/form/keymaps-form.jsx delete mode 100644 src/settings/components/form/keymaps-form.scss delete mode 100644 src/settings/components/form/properties-form.jsx delete mode 100644 src/settings/components/form/properties-form.scss delete mode 100644 src/settings/components/form/search-form.jsx delete mode 100644 src/settings/components/form/search-form.scss create mode 100644 src/settings/components/ui/AddButton.jsx create mode 100644 src/settings/components/ui/AddButton.scss create mode 100644 src/settings/components/ui/DeleteButton.jsx create mode 100644 src/settings/components/ui/DeleteButton.scss create mode 100644 src/settings/components/ui/Input.jsx create mode 100644 src/settings/components/ui/Input.scss delete mode 100644 src/settings/components/ui/add-button.jsx delete mode 100644 src/settings/components/ui/add-button.scss delete mode 100644 src/settings/components/ui/delete-button.jsx delete mode 100644 src/settings/components/ui/delete-button.scss delete mode 100644 src/settings/components/ui/input.jsx delete mode 100644 src/settings/components/ui/input.scss create mode 100644 src/settings/keymaps.js diff --git a/src/settings/actions/setting.js b/src/settings/actions/setting.js index 0277159..8844252 100644 --- a/src/settings/actions/setting.js +++ b/src/settings/actions/setting.js @@ -1,8 +1,8 @@ import actions from 'settings/actions'; import * as validator from 'shared/settings/validator'; -import KeymapsForm from '../components/form/keymaps-form'; import * as settingsValues from 'shared/settings/values'; import * as settingsStorage from 'shared/settings/storage'; +import keymaps from '../keymaps'; const load = async() => { let settings = await settingsStorage.loadRaw(); @@ -29,8 +29,7 @@ const save = async(settings) => { const switchToForm = (json) => { try { validator.validate(JSON.parse(json)); - // AllowdOps filters operations, this is dirty dependency - let form = settingsValues.formFromJson(json, KeymapsForm.AllowdOps); + let form = settingsValues.formFromJson(json, keymaps.allowedOps); return { type: actions.SETTING_SWITCH_TO_FORM, form, diff --git a/src/settings/components/form/BlacklistForm.jsx b/src/settings/components/form/BlacklistForm.jsx new file mode 100644 index 0000000..13571f1 --- /dev/null +++ b/src/settings/components/form/BlacklistForm.jsx @@ -0,0 +1,52 @@ +import './BlacklistForm.scss'; +import AddButton from '../ui/AddButton'; +import DeleteButton from '../ui/DeleteButton'; +import React from 'react'; + +class BlacklistForm extends React.Component { + + render() { + let value = this.props.value; + if (!value) { + value = []; + } + + return
    + { + value.map((url, index) => { + return
    + + +
    ; + }) + } + +
    ; + } + + bindValue(e) { + if (!this.props.onChange) { + return; + } + + let name = e.target.name; + let index = e.target.getAttribute('data-index'); + let next = this.props.value ? this.props.value.slice() : []; + + if (name === 'url') { + next[index] = e.target.value; + } else if (name === 'add') { + next.push(''); + } else if (name === 'delete') { + next.splice(index, 1); + } + + this.props.onChange(next); + } +} + +export default BlacklistForm; diff --git a/src/settings/components/form/BlacklistForm.scss b/src/settings/components/form/BlacklistForm.scss new file mode 100644 index 0000000..a230d0d --- /dev/null +++ b/src/settings/components/form/BlacklistForm.scss @@ -0,0 +1,9 @@ +.form-blacklist-form { + &-row { + display: flex; + + .column-url { + flex: 1; + } + } +} diff --git a/src/settings/components/form/KeymapsForm.jsx b/src/settings/components/form/KeymapsForm.jsx new file mode 100644 index 0000000..25a3710 --- /dev/null +++ b/src/settings/components/form/KeymapsForm.jsx @@ -0,0 +1,47 @@ +import './KeymapsForm.scss'; +import React from 'react'; +import Input from '../ui/Input'; +import keymaps from '../../keymaps'; + +class KeymapsForm extends React.Component { + + render() { + let values = this.props.value; + if (!values) { + values = {}; + } + return
    + { + keymaps.fields.map((group, index) => { + return
    + { + group.map((field) => { + let name = field[0]; + let label = field[1]; + let value = values[name]; + return ; + }) + } +
    ; + }) + } +
    ; + } + + bindValue(e) { + if (!this.props.onChange) { + return; + } + + let next = { ...this.props.value }; + next[e.target.name] = e.target.value; + + this.props.onChange(next); + } +} + +export default KeymapsForm; diff --git a/src/settings/components/form/KeymapsForm.scss b/src/settings/components/form/KeymapsForm.scss new file mode 100644 index 0000000..1a4e5cd --- /dev/null +++ b/src/settings/components/form/KeymapsForm.scss @@ -0,0 +1,11 @@ +.form-keymaps-form { + column-count: 3; + + &-field-group { + margin-top: 24px; + } + + &-field-group:first-of-type { + margin-top: 24px; + } +} diff --git a/src/settings/components/form/PropertiesForm.jsx b/src/settings/components/form/PropertiesForm.jsx new file mode 100644 index 0000000..77991fc --- /dev/null +++ b/src/settings/components/form/PropertiesForm.jsx @@ -0,0 +1,60 @@ +import './PropertiesForm.scss'; +import React from 'react'; + +class PropertiesForm extends React.Component { + + render() { + let types = this.props.types; + let value = this.props.value; + if (!value) { + value = {}; + } + + return
    + { + Object.keys(types).map((name) => { + let type = types[name]; + let inputType = null; + if (type === 'string') { + inputType = 'text'; + } else if (type === 'number') { + inputType = 'number'; + } else if (type === 'boolean') { + inputType = 'checkbox'; + } + return
    + +
    ; + }) + } +
    ; + } + + bindValue(e) { + if (!this.props.onChange) { + return; + } + + let name = e.target.name; + let next = { ...this.props.value }; + if (e.target.type.toLowerCase() === 'checkbox') { + next[name] = e.target.checked; + } else if (e.target.type.toLowerCase() === 'number') { + next[name] = Number(e.target.value); + } else { + next[name] = e.target.value; + } + + this.props.onChange(next); + } +} + +export default PropertiesForm; diff --git a/src/settings/components/form/PropertiesForm.scss b/src/settings/components/form/PropertiesForm.scss new file mode 100644 index 0000000..7c9e167 --- /dev/null +++ b/src/settings/components/form/PropertiesForm.scss @@ -0,0 +1,12 @@ +.form-properties-form { + &-row { + .column-name { + display: inline-block; + min-width: 5rem; + font-weight: bold; + } + .column-input { + line-height: 2.2rem; + } + } +} diff --git a/src/settings/components/form/SearchForm.jsx b/src/settings/components/form/SearchForm.jsx new file mode 100644 index 0000000..f52fd5f --- /dev/null +++ b/src/settings/components/form/SearchForm.jsx @@ -0,0 +1,78 @@ +import './SearchForm.scss'; +import React from 'react'; +import AddButton from '../ui/AddButton'; +import DeleteButton from '../ui/DeleteButton'; + +class SearchForm extends React.Component { + + render() { + let value = this.props.value; + if (!value) { + value = { default: '', engines: []}; + } + if (!value.engines) { + value.engines = []; + } + + return
    +
    +
    Name
    +
    URL
    +
    Default
    +
    + { + value.engines.map((engine, index) => { + return
    + + +
    + + +
    +
    ; + }) + } + +
    ; + } + + bindValue(e) { + if (!this.props.onChange) { + return; + } + + let value = this.props.value; + let name = e.target.name; + let index = e.target.getAttribute('data-index'); + let next = { + default: value.default, + engines: value.engines ? value.engines.slice() : [], + }; + + if (name === 'name') { + next.engines[index][0] = e.target.value; + next.default = this.props.value.engines[index][0]; + } else if (name === 'url') { + next.engines[index][1] = e.target.value; + } else if (name === 'default') { + next.default = this.props.value.engines[index][0]; + } else if (name === 'add') { + next.engines.push(['', '']); + } else if (name === 'delete') { + next.engines.splice(index, 1); + } + + this.props.onChange(next); + } +} + +export default SearchForm; diff --git a/src/settings/components/form/SearchForm.scss b/src/settings/components/form/SearchForm.scss new file mode 100644 index 0000000..26b2f44 --- /dev/null +++ b/src/settings/components/form/SearchForm.scss @@ -0,0 +1,28 @@ +.form-search-form { + @mixin row-base { + display: flex; + + .column-name { + flex: 1; + min-width: 0; + } + .column-url { + flex: 5; + min-width: 0; + } + .column-option { + text-align: right; + flex-basis: 5rem; + } + } + + &-header { + @include row-base; + + font-weight: bold; + } + + &-row { + @include row-base; + } +} diff --git a/src/settings/components/form/blacklist-form.jsx b/src/settings/components/form/blacklist-form.jsx deleted file mode 100644 index 492c3af..0000000 --- a/src/settings/components/form/blacklist-form.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import './blacklist-form.scss'; -import AddButton from '../ui/add-button'; -import DeleteButton from '../ui/delete-button'; -import React from 'react'; - -class BlacklistForm extends React.Component { - - render() { - let value = this.props.value; - if (!value) { - value = []; - } - - return
    - { - value.map((url, index) => { - return
    - - -
    ; - }) - } - -
    ; - } - - bindValue(e) { - if (!this.props.onChange) { - return; - } - - let name = e.target.name; - let index = e.target.getAttribute('data-index'); - let next = this.props.value ? this.props.value.slice() : []; - - if (name === 'url') { - next[index] = e.target.value; - } else if (name === 'add') { - next.push(''); - } else if (name === 'delete') { - next.splice(index, 1); - } - - this.props.onChange(next); - } -} - -export default BlacklistForm; diff --git a/src/settings/components/form/blacklist-form.scss b/src/settings/components/form/blacklist-form.scss deleted file mode 100644 index a230d0d..0000000 --- a/src/settings/components/form/blacklist-form.scss +++ /dev/null @@ -1,9 +0,0 @@ -.form-blacklist-form { - &-row { - display: flex; - - .column-url { - flex: 1; - } - } -} diff --git a/src/settings/components/form/keymaps-form.jsx b/src/settings/components/form/keymaps-form.jsx deleted file mode 100644 index 8c0a83f..0000000 --- a/src/settings/components/form/keymaps-form.jsx +++ /dev/null @@ -1,118 +0,0 @@ -import './keymaps-form.scss'; -import React from 'react'; -import Input from '../ui/input'; - -const KeyMapFields = [ - [ - ['scroll.vertically?{"count":1}', 'Scroll down'], - ['scroll.vertically?{"count":-1}', 'Scroll up'], - ['scroll.horizonally?{"count":-1}', 'Scroll left'], - ['scroll.horizonally?{"count":1}', 'Scroll right'], - ['scroll.home', 'Scroll to leftmost'], - ['scroll.end', 'Scroll to rightmost'], - ['scroll.top', 'Scroll to top'], - ['scroll.bottom', 'Scroll to bottom'], - ['scroll.pages?{"count":-0.5}', 'Scroll up by half of screen'], - ['scroll.pages?{"count":0.5}', 'Scroll down by half of screen'], - ['scroll.pages?{"count":-1}', 'Scroll up by a screen'], - ['scroll.pages?{"count":1}', 'Scroll down by a screen'], - ], [ - ['mark.set.prefix', 'Set mark at current position'], - ['mark.jump.prefix', 'Jump to the mark'], - ], [ - ['tabs.close', 'Close a tab'], - ['tabs.close.right', 'Close tabs to the right'], - ['tabs.reopen', 'Reopen closed tab'], - ['tabs.next?{"count":1}', 'Select next Tab'], - ['tabs.prev?{"count":1}', 'Select prev Tab'], - ['tabs.first', 'Select first tab'], - ['tabs.last', 'Select last tab'], - ['tabs.reload?{"cache":false}', 'Reload current tab'], - ['tabs.reload?{"cache":true}', 'Reload with no caches'], - ['tabs.pin.toggle', 'Toggle pinned state'], - ['tabs.duplicate', 'Duplicate a tab'], - ], [ - ['follow.start?{"newTab":false}', 'Follow a link'], - ['follow.start?{"newTab":true}', 'Follow a link in new tab'], - ['navigate.history.prev', 'Go back in histories'], - ['navigate.history.next', 'Go forward in histories'], - ['navigate.link.next', 'Open next link'], - ['navigate.link.prev', 'Open previous link'], - ['navigate.parent', 'Go to parent directory'], - ['navigate.root', 'Go to root directory'], - ['page.source', 'Open page source'], - ['page.home', 'Open start page to current tab'], - ['page.home?{"newTab":true}', 'Open start page in new tab'], - ['focus.input', 'Focus input'], - ], [ - ['find.start', 'Start find mode'], - ['find.next', 'Find next word'], - ['find.prev', 'Find previous word'], - ], [ - ['command.show', 'Open console'], - ['command.show.open?{"alter":false}', 'Open URL'], - ['command.show.open?{"alter":true}', 'Alter URL'], - ['command.show.tabopen?{"alter":false}', 'Open URL in new Tab'], - ['command.show.tabopen?{"alter":true}', 'Alter URL in new Tab'], - ['command.show.winopen?{"alter":false}', 'Open URL in new window'], - ['command.show.winopen?{"alter":true}', 'Alter URL in new window'], - ['command.show.buffer', 'Open buffer command'], - ['command.show.addbookmark?{"alter":true}', 'Open addbookmark command'], - ], [ - ['addon.toggle.enabled', 'Enable or disable'], - ['urls.yank', 'Copy current URL'], - ['urls.paste?{"newTab":false}', 'Open clipboard\'s URL in current tab'], - ['urls.paste?{"newTab":true}', 'Open clipboard\'s URL in new tab'], - ['zoom.in', 'Zoom-in'], - ['zoom.out', 'Zoom-out'], - ['zoom.neutral', 'Reset zoom level'], - ['page.source', 'Open a page source'], - ] -]; - -const AllowdOps = [].concat(...KeyMapFields.map(group => group.map(e => e[0]))); - -class KeymapsForm extends React.Component { - - render() { - let values = this.props.value; - if (!values) { - values = {}; - } - return
    - { - KeyMapFields.map((group, index) => { - return
    - { - group.map((field) => { - let name = field[0]; - let label = field[1]; - let value = values[name]; - return ; - }) - } -
    ; - }) - } -
    ; - } - - bindValue(e) { - if (!this.props.onChange) { - return; - } - - let next = { ...this.props.value }; - next[e.target.name] = e.target.value; - - this.props.onChange(next); - } -} - -KeymapsForm.AllowdOps = AllowdOps; - -export default KeymapsForm; diff --git a/src/settings/components/form/keymaps-form.scss b/src/settings/components/form/keymaps-form.scss deleted file mode 100644 index 1a4e5cd..0000000 --- a/src/settings/components/form/keymaps-form.scss +++ /dev/null @@ -1,11 +0,0 @@ -.form-keymaps-form { - column-count: 3; - - &-field-group { - margin-top: 24px; - } - - &-field-group:first-of-type { - margin-top: 24px; - } -} diff --git a/src/settings/components/form/properties-form.jsx b/src/settings/components/form/properties-form.jsx deleted file mode 100644 index 7d591d5..0000000 --- a/src/settings/components/form/properties-form.jsx +++ /dev/null @@ -1,60 +0,0 @@ -import './properties-form.scss'; -import React from 'react'; - -class PropertiesForm extends React.Component { - - render() { - let types = this.props.types; - let value = this.props.value; - if (!value) { - value = {}; - } - - return
    - { - Object.keys(types).map((name) => { - let type = types[name]; - let inputType = null; - if (type === 'string') { - inputType = 'text'; - } else if (type === 'number') { - inputType = 'number'; - } else if (type === 'boolean') { - inputType = 'checkbox'; - } - return
    - -
    ; - }) - } -
    ; - } - - bindValue(e) { - if (!this.props.onChange) { - return; - } - - let name = e.target.name; - let next = { ...this.props.value }; - if (e.target.type.toLowerCase() === 'checkbox') { - next[name] = e.target.checked; - } else if (e.target.type.toLowerCase() === 'number') { - next[name] = Number(e.target.value); - } else { - next[name] = e.target.value; - } - - this.props.onChange(next); - } -} - -export default PropertiesForm; diff --git a/src/settings/components/form/properties-form.scss b/src/settings/components/form/properties-form.scss deleted file mode 100644 index 7c9e167..0000000 --- a/src/settings/components/form/properties-form.scss +++ /dev/null @@ -1,12 +0,0 @@ -.form-properties-form { - &-row { - .column-name { - display: inline-block; - min-width: 5rem; - font-weight: bold; - } - .column-input { - line-height: 2.2rem; - } - } -} diff --git a/src/settings/components/form/search-form.jsx b/src/settings/components/form/search-form.jsx deleted file mode 100644 index 81204f3..0000000 --- a/src/settings/components/form/search-form.jsx +++ /dev/null @@ -1,78 +0,0 @@ -import './search-form.scss'; -import React from 'react'; -import AddButton from '../ui/add-button'; -import DeleteButton from '../ui/delete-button'; - -class SearchForm extends React.Component { - - render() { - let value = this.props.value; - if (!value) { - value = { default: '', engines: []}; - } - if (!value.engines) { - value.engines = []; - } - - return
    -
    -
    Name
    -
    URL
    -
    Default
    -
    - { - value.engines.map((engine, index) => { - return
    - - -
    - - -
    -
    ; - }) - } - -
    ; - } - - bindValue(e) { - if (!this.props.onChange) { - return; - } - - let value = this.props.value; - let name = e.target.name; - let index = e.target.getAttribute('data-index'); - let next = { - default: value.default, - engines: value.engines ? value.engines.slice() : [], - }; - - if (name === 'name') { - next.engines[index][0] = e.target.value; - next.default = this.props.value.engines[index][0]; - } else if (name === 'url') { - next.engines[index][1] = e.target.value; - } else if (name === 'default') { - next.default = this.props.value.engines[index][0]; - } else if (name === 'add') { - next.engines.push(['', '']); - } else if (name === 'delete') { - next.engines.splice(index, 1); - } - - this.props.onChange(next); - } -} - -export default SearchForm; diff --git a/src/settings/components/form/search-form.scss b/src/settings/components/form/search-form.scss deleted file mode 100644 index 26b2f44..0000000 --- a/src/settings/components/form/search-form.scss +++ /dev/null @@ -1,28 +0,0 @@ -.form-search-form { - @mixin row-base { - display: flex; - - .column-name { - flex: 1; - min-width: 0; - } - .column-url { - flex: 5; - min-width: 0; - } - .column-option { - text-align: right; - flex-basis: 5rem; - } - } - - &-header { - @include row-base; - - font-weight: bold; - } - - &-row { - @include row-base; - } -} diff --git a/src/settings/components/index.jsx b/src/settings/components/index.jsx index 9dae25e..affa2e9 100644 --- a/src/settings/components/index.jsx +++ b/src/settings/components/index.jsx @@ -1,11 +1,11 @@ import './site.scss'; import React from 'react'; import { connect } from 'react-redux'; -import Input from './ui/input'; -import SearchForm from './form/search-form'; -import KeymapsForm from './form/keymaps-form'; -import BlacklistForm from './form/blacklist-form'; -import PropertiesForm from './form/properties-form'; +import Input from './ui/Input'; +import SearchForm from './form/SearchForm'; +import KeymapsForm from './form/KeymapsForm'; +import BlacklistForm from './form/BlacklistForm'; +import PropertiesForm from './form/PropertiesForm'; import * as properties from 'shared/settings/properties'; import * as settingActions from 'settings/actions/setting'; @@ -136,7 +136,7 @@ class SettingsComponent extends React.Component { this.props.dispatch(settingActions.switchToForm(this.props.json)); } - let settings = this.props.getState(); + let settings = this.props.store.getState(); this.props.dispatch(settingActions.save(settings)); } } diff --git a/src/settings/components/ui/AddButton.jsx b/src/settings/components/ui/AddButton.jsx new file mode 100644 index 0000000..185a03b --- /dev/null +++ b/src/settings/components/ui/AddButton.jsx @@ -0,0 +1,12 @@ +import './AddButton.scss'; +import React from 'react'; + +class AddButton extends React.Component { + render() { + return ; + } +} + +export default AddButton; diff --git a/src/settings/components/ui/AddButton.scss b/src/settings/components/ui/AddButton.scss new file mode 100644 index 0000000..beb5688 --- /dev/null +++ b/src/settings/components/ui/AddButton.scss @@ -0,0 +1,13 @@ +.ui-add-button { + border: none; + padding: 4; + display: inline; + background: none; + font-weight: bold; + color: green; + cursor: pointer; + + &:hover { + color: darkgreen; + } +} diff --git a/src/settings/components/ui/DeleteButton.jsx b/src/settings/components/ui/DeleteButton.jsx new file mode 100644 index 0000000..75811cd --- /dev/null +++ b/src/settings/components/ui/DeleteButton.jsx @@ -0,0 +1,12 @@ +import './DeleteButton.scss'; +import React from 'react'; + +class DeleteButton extends React.Component { + render() { + return ; + } +} + +export default DeleteButton; diff --git a/src/settings/components/ui/DeleteButton.scss b/src/settings/components/ui/DeleteButton.scss new file mode 100644 index 0000000..5932a72 --- /dev/null +++ b/src/settings/components/ui/DeleteButton.scss @@ -0,0 +1,13 @@ + +.ui-delete-button { + border: none; + padding: 4; + display: inline; + background: none; + color: red; + cursor: pointer; + + &:hover { + color: darkred; + } +} diff --git a/src/settings/components/ui/Input.jsx b/src/settings/components/ui/Input.jsx new file mode 100644 index 0000000..d090f5b --- /dev/null +++ b/src/settings/components/ui/Input.jsx @@ -0,0 +1,52 @@ +import React from 'react'; +import './Input.scss'; + +class Input extends React.Component { + + renderText(props) { + let inputClassName = props.error ? 'input-error' : ''; + return
    + + +
    ; + } + + renderRadio(props) { + let inputClassName = props.error ? 'input-error' : ''; + return
    + +
    ; + } + + renderTextArea(props) { + let inputClassName = props.error ? 'input-error' : ''; + return
    + +