diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/background/domains/Completions.js | 6 | ||||
-rw-r--r-- | src/console/components/Console.jsx (renamed from src/console/components/console.jsx) | 54 | ||||
-rw-r--r-- | src/console/components/console/Completion.jsx (renamed from src/console/components/console/completion.jsx) | 51 | ||||
-rw-r--r-- | src/console/components/console/CompletionItem.jsx | 28 | ||||
-rw-r--r-- | src/console/components/console/CompletionTitle.jsx | 14 | ||||
-rw-r--r-- | src/console/components/console/Input.jsx (renamed from src/console/components/console/input.jsx) | 17 | ||||
-rw-r--r-- | src/console/components/console/Message.jsx (renamed from src/console/components/console/message.jsx) | 13 | ||||
-rw-r--r-- | src/console/index.html | 4 | ||||
-rw-r--r-- | src/console/index.jsx | 14 | ||||
-rw-r--r-- | src/settings/actions/setting.js | 7 | ||||
-rw-r--r-- | src/settings/components/form/BlacklistForm.jsx (renamed from src/settings/components/form/blacklist-form.jsx) | 47 | ||||
-rw-r--r-- | src/settings/components/form/BlacklistForm.scss (renamed from src/settings/components/form/blacklist-form.scss) | 0 | ||||
-rw-r--r-- | src/settings/components/form/KeymapsForm.jsx | 51 | ||||
-rw-r--r-- | src/settings/components/form/KeymapsForm.scss (renamed from src/settings/components/form/keymaps-form.scss) | 0 | ||||
-rw-r--r-- | src/settings/components/form/PropertiesForm.jsx (renamed from src/settings/components/form/properties-form.jsx) | 25 | ||||
-rw-r--r-- | src/settings/components/form/PropertiesForm.scss (renamed from src/settings/components/form/properties-form.scss) | 0 | ||||
-rw-r--r-- | src/settings/components/form/SearchForm.jsx (renamed from src/settings/components/form/search-form.jsx) | 44 | ||||
-rw-r--r-- | src/settings/components/form/SearchForm.scss (renamed from src/settings/components/form/search-form.scss) | 0 | ||||
-rw-r--r-- | src/settings/components/index.jsx | 29 | ||||
-rw-r--r-- | src/settings/components/ui/AddButton.jsx (renamed from src/settings/components/ui/add-button.jsx) | 6 | ||||
-rw-r--r-- | src/settings/components/ui/AddButton.scss (renamed from src/settings/components/ui/add-button.scss) | 0 | ||||
-rw-r--r-- | src/settings/components/ui/DeleteButton.jsx (renamed from src/settings/components/ui/delete-button.jsx) | 6 | ||||
-rw-r--r-- | src/settings/components/ui/DeleteButton.scss (renamed from src/settings/components/ui/delete-button.scss) | 0 | ||||
-rw-r--r-- | src/settings/components/ui/Input.jsx (renamed from src/settings/components/ui/input.jsx) | 14 | ||||
-rw-r--r-- | src/settings/components/ui/Input.scss (renamed from src/settings/components/ui/input.scss) | 0 | ||||
-rw-r--r-- | src/settings/index.jsx | 9 | ||||
-rw-r--r-- | src/settings/keymaps.js (renamed from src/settings/components/form/keymaps-form.jsx) | 56 |
27 files changed, 308 insertions, 187 deletions
diff --git a/src/background/domains/Completions.js b/src/background/domains/Completions.js index 4e4219f..f399743 100644 --- a/src/background/domains/Completions.js +++ b/src/background/domains/Completions.js @@ -19,9 +19,9 @@ export default class Completions { })); } - static EMPTY_COMPLETIONS = new Completions([]); - static empty() { - return Completions.EMPTY_COMPLETIONS; + return EMPTY_COMPLETIONS; } } + +let EMPTY_COMPLETIONS = new Completions([]); diff --git a/src/console/components/console.jsx b/src/console/components/Console.jsx index 7994f78..5427e43 100644 --- a/src/console/components/console.jsx +++ b/src/console/components/Console.jsx @@ -1,17 +1,18 @@ import './console.scss'; -import { connect } from 'preact-redux'; -import { Component, h } from 'preact'; -import Input from './console/input'; -import Completion from './console/completion'; -import Message from './console/message'; +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 ConsoleComponent extends Component { +class Console 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 +22,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: @@ -80,11 +81,11 @@ class ConsoleComponent extends Component { } } - onInput(e) { + onChange(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 +95,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') { @@ -117,7 +118,7 @@ class ConsoleComponent extends Component { mode={this.props.mode} onBlur={this.onBlur.bind(this)} onKeyDown={this.onKeyDown.bind(this)} - onInput={this.onInput.bind(this)} + onChange={this.onChange.bind(this)} value={this.props.consoleText} /> </div>; @@ -126,6 +127,8 @@ class ConsoleComponent extends Component { return <Message mode={ this.props.mode } > { this.props.messageText } </Message>; + default: + return null; } } @@ -135,5 +138,12 @@ class ConsoleComponent extends Component { } } +Console.propTypes = { + mode: PropTypes.string, + consoleText: PropTypes.string, + messageText: PropTypes.string, + children: PropTypes.string, +}; + const mapStateToProps = state => state; -export default connect(mapStateToProps)(ConsoleComponent); +export default connect(mapStateToProps)(Console); diff --git a/src/console/components/console/completion.jsx b/src/console/components/console/Completion.jsx index d836cec..5477cb6 100644 --- a/src/console/components/console/completion.jsx +++ b/src/console/components/console/Completion.jsx @@ -1,29 +1,9 @@ -import { Component, h } from 'preact'; +import React from 'react'; +import PropTypes from 'prop-types'; +import CompletionItem from './CompletionItem'; +import CompletionTitle from './CompletionTitle'; -const CompletionTitle = (props) => { - return <li className='vimvixen-console-completion-title' >{props.title}</li>; -}; - -const CompletionItem = (props) => { - let className = 'vimvixen-console-completion-item'; - if (props.highlight) { - className += ' vimvixen-completion-selected'; - } - return <li - className={className} - style={{ backgroundImage: 'url(' + props.icon + ')' }} - > - <span - className='vimvixen-console-completion-item-caption' - >{props.caption}</span> - <span - className='vimvixen-console-completion-item-url' - >{props.url}</span> - </li>; -}; - - -class CompletionComponent extends Component { +class Completion extends React.Component { constructor() { super(); this.state = { viewOffset: 0, select: -1 }; @@ -63,9 +43,13 @@ class CompletionComponent extends Component { let index = 0; for (let group of this.props.completions) { - eles.push(<CompletionTitle title={ group.name }/>); + eles.push(<CompletionTitle + key={`group-${index}`} + title={ group.name } + />); for (let item of group.items) { eles.push(<CompletionItem + key={`item-${index}`} icon={item.icon} caption={item.caption} url={item.url} @@ -86,4 +70,17 @@ class CompletionComponent extends Component { } } -export default CompletionComponent; +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 <li + className={className} + style={{ backgroundImage: 'url(' + props.icon + ')' }} + > + <span + className='vimvixen-console-completion-item-caption' + >{props.caption}</span> + <span + className='vimvixen-console-completion-item-url' + >{props.url}</span> + </li>; +}; + +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 <li className='vimvixen-console-completion-title'> + {props.title} + </li>; +}; + +CompletionTitle.propTypes = { + title: PropTypes.string, +}; + +export default CompletionTitle; diff --git a/src/console/components/console/input.jsx b/src/console/components/console/Input.jsx index d59e6e7..cbd3348 100644 --- a/src/console/components/console/input.jsx +++ b/src/console/components/console/Input.jsx @@ -1,6 +1,7 @@ -import { Component, h } from 'preact'; +import React from 'react'; +import PropTypes from 'prop-types'; -export default class InputComponent extends Component { +class Input extends React.Component { focus() { this.input.focus(); } @@ -23,10 +24,20 @@ export default class InputComponent extends Component { ref={(c) => { this.input = c; }} onBlur={this.props.onBlur} onKeyDown={this.props.onKeyDown} - onInput={this.props.onInput} + onChange={this.props.onChange} value={this.props.value} /> </div> ); } } + +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 index 5b60af4..dd96248 100644 --- a/src/console/components/console/message.jsx +++ b/src/console/components/console/Message.jsx @@ -1,6 +1,7 @@ -import { h } from 'preact'; +import React from 'react'; +import PropTypes from 'prop-types'; -export default function Message(props) { +const Message = (props) => { switch (props.mode) { case 'error': return ( @@ -15,4 +16,10 @@ export default function Message(props) { </p> ); } -} +}; + +Message.propTypes = { + children: PropTypes.string, +}; + +export default Message; 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 @@ <title>VimVixen console</title> <script src='console.js'></script> </head> - <body class='vimvixen-console'></body> + <body> + <div id='vimvixen-console' class='vimvixen-console'></div> + </body> </html> diff --git a/src/console/index.jsx b/src/console/index.jsx index dfd323e..3190a9a 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 Console from './components/console'; - -import { render, h } from 'preact'; +import { Provider } from 'react-redux'; +import Console from './components/Console'; +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( <Provider store={store} > <Console></Console> </Provider>, - document.body); + wrapper); }); const onMessage = (message) => { diff --git a/src/settings/actions/setting.js b/src/settings/actions/setting.js index 0277159..db63a45 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, @@ -61,4 +60,4 @@ const set = (settings) => { }; }; -export { load, save, switchToForm, switchToJson }; +export { load, save, set, switchToForm, switchToJson }; diff --git a/src/settings/components/form/blacklist-form.jsx b/src/settings/components/form/BlacklistForm.jsx index 7ae9652..c470758 100644 --- a/src/settings/components/form/blacklist-form.jsx +++ b/src/settings/components/form/BlacklistForm.jsx @@ -1,38 +1,34 @@ -import './blacklist-form.scss'; -import AddButton from '../ui/add-button'; -import DeleteButton from '../ui/delete-button'; -import { h, Component } from 'preact'; +import './BlacklistForm.scss'; +import AddButton from '../ui/AddButton'; +import DeleteButton from '../ui/DeleteButton'; +import React from 'react'; +import PropTypes from 'prop-types'; -class BlacklistForm extends Component { +class BlacklistForm extends React.Component { render() { - let value = this.props.value; - if (!value) { - value = []; - } - return <div className='form-blacklist-form'> { - value.map((url, index) => { + this.props.value.map((url, index) => { return <div key={index} className='form-blacklist-form-row'> <input data-index={index} type='text' name='url' className='column-url' value={url} - onChange={this.bindValue.bind(this)} /> + onChange={this.bindValue.bind(this)} + onBlur={this.props.onBlur} + /> <DeleteButton data-index={index} name='delete' - onClick={this.bindValue.bind(this)} /> + onClick={this.bindValue.bind(this)} + onBlur={this.props.onBlur} + /> </div>; }) } - <AddButton name='add' style='float:right' + <AddButton name='add' style={{ float: 'right' }} onClick={this.bindValue.bind(this)} /> </div>; } 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() : []; @@ -46,7 +42,22 @@ class BlacklistForm extends Component { } this.props.onChange(next); + if (name === 'delete') { + this.props.onBlur(); + } } } +BlacklistForm.propTypes = { + value: PropTypes.arrayOf(PropTypes.string), + onChange: PropTypes.func, + onBlur: PropTypes.func, +}; + +BlacklistForm.defaultProps = { + value: [], + onChange: () => {}, + onBlur: () => {}, +}; + export default BlacklistForm; diff --git a/src/settings/components/form/blacklist-form.scss b/src/settings/components/form/BlacklistForm.scss index a230d0d..a230d0d 100644 --- a/src/settings/components/form/blacklist-form.scss +++ b/src/settings/components/form/BlacklistForm.scss diff --git a/src/settings/components/form/KeymapsForm.jsx b/src/settings/components/form/KeymapsForm.jsx new file mode 100644 index 0000000..01acf61 --- /dev/null +++ b/src/settings/components/form/KeymapsForm.jsx @@ -0,0 +1,51 @@ +import './KeymapsForm.scss'; +import React from 'react'; +import PropTypes from 'prop-types'; +import Input from '../ui/Input'; +import keymaps from '../../keymaps'; + +class KeymapsForm extends React.Component { + + render() { + return <div className='form-keymaps-form'> + { + keymaps.fields.map((group, index) => { + return <div key={index} className='form-keymaps-form-field-group'> + { + group.map((field) => { + let name = field[0]; + let label = field[1]; + let value = this.props.value[name] || ''; + return <Input + type='text' id={name} name={name} key={name} + label={label} value={value} + onChange={this.bindValue.bind(this)} + onBlur={this.props.onBlur} + />; + }) + } + </div>; + }) + } + </div>; + } + + bindValue(e) { + let next = { ...this.props.value }; + next[e.target.name] = e.target.value; + + this.props.onChange(next); + } +} + +KeymapsForm.propTypes = { + value: PropTypes.objectOf(PropTypes.string), + onChange: PropTypes.func, +}; + +KeymapsForm.defaultProps = { + value: {}, + onChange: () => {}, +}; + +export default KeymapsForm; diff --git a/src/settings/components/form/keymaps-form.scss b/src/settings/components/form/KeymapsForm.scss index 1a4e5cd..1a4e5cd 100644 --- a/src/settings/components/form/keymaps-form.scss +++ b/src/settings/components/form/KeymapsForm.scss diff --git a/src/settings/components/form/properties-form.jsx b/src/settings/components/form/PropertiesForm.jsx index ceb79d7..979fdd8 100644 --- a/src/settings/components/form/properties-form.jsx +++ b/src/settings/components/form/PropertiesForm.jsx @@ -1,14 +1,12 @@ -import './properties-form.scss'; -import { h, Component } from 'preact'; +import './PropertiesForm.scss'; +import React from 'react'; +import PropTypes from 'prop-types'; -class PropertiesForm extends Component { +class PropertiesForm extends React.Component { render() { let types = this.props.types; let value = this.props.value; - if (!value) { - value = {}; - } return <div className='form-properties-form'> { @@ -29,6 +27,7 @@ class PropertiesForm extends Component { className='column-input' value={value[name] ? value[name] : ''} onChange={this.bindValue.bind(this)} + onBlur={this.props.onBlur} checked={value[name]} /> </label> @@ -39,10 +38,6 @@ class PropertiesForm extends Component { } bindValue(e) { - if (!this.props.onChange) { - return; - } - let name = e.target.name; let next = { ...this.props.value }; if (e.target.type.toLowerCase() === 'checkbox') { @@ -57,4 +52,14 @@ class PropertiesForm extends Component { } } +PropertiesForm.propTypes = { + value: PropTypes.objectOf(PropTypes.any), + onChange: PropTypes.func, +}; + +PropertiesForm.defaultProps = { + value: {}, + onChange: () => {}, +}; + export default PropertiesForm; diff --git a/src/settings/components/form/properties-form.scss b/src/settings/components/form/PropertiesForm.scss index 7c9e167..7c9e167 100644 --- a/src/settings/components/form/properties-form.scss +++ b/src/settings/components/form/PropertiesForm.scss diff --git a/src/settings/components/form/search-form.jsx b/src/settings/components/form/SearchForm.jsx index 2d5f01b..6b0bd01 100644 --- a/src/settings/components/form/search-form.jsx +++ b/src/settings/components/form/SearchForm.jsx @@ -1,15 +1,13 @@ -import './search-form.scss'; -import { h, Component } from 'preact'; -import AddButton from '../ui/add-button'; -import DeleteButton from '../ui/delete-button'; +import './SearchForm.scss'; +import React from 'react'; +import PropTypes from 'prop-types'; +import AddButton from '../ui/AddButton'; +import DeleteButton from '../ui/DeleteButton'; -class SearchForm extends Component { +class SearchForm extends React.Component { render() { let value = this.props.value; - if (!value) { - value = { default: '', engines: []}; - } if (!value.engines) { value.engines = []; } @@ -25,11 +23,15 @@ class SearchForm extends Component { return <div key={index} className='form-search-form-row'> <input data-index={index} type='text' name='name' className='column-name' value={engine[0]} - onChange={this.bindValue.bind(this)} /> + onChange={this.bindValue.bind(this)} + onBlur={this.props.onBlur} + /> <input data-index={index} type='text' name='url' placeholder='http://example.com/?q={}' className='column-url' value={engine[1]} - onChange={this.bindValue.bind(this)} /> + onChange={this.bindValue.bind(this)} + onBlur={this.props.onBlur} + /> <div className='column-option'> <input data-index={index} type='radio' name='default' checked={value.default === engine[0]} @@ -40,16 +42,12 @@ class SearchForm extends Component { </div>; }) } - <AddButton name='add' style='float:right' + <AddButton name='add' style={{ float: 'right' }} onClick={this.bindValue.bind(this)} /> </div>; } bindValue(e) { - if (!this.props.onChange) { - return; - } - let value = this.props.value; let name = e.target.name; let index = e.target.getAttribute('data-index'); @@ -72,7 +70,23 @@ class SearchForm extends Component { } this.props.onChange(next); + if (name === 'delete' || name === 'default') { + this.props.onBlur(); + } } } +SearchForm.propTypes = { + value: PropTypes.shape({ + default: PropTypes.string, + engines: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)), + }), + onChange: PropTypes.func, +}; + +SearchForm.defaultProps = { + value: { default: '', engines: []}, + onChange: () => {}, +}; + export default SearchForm; diff --git a/src/settings/components/form/search-form.scss b/src/settings/components/form/SearchForm.scss index 26b2f44..26b2f44 100644 --- a/src/settings/components/form/search-form.scss +++ b/src/settings/components/form/SearchForm.scss diff --git a/src/settings/components/index.jsx b/src/settings/components/index.jsx index 9633359..4ef59d7 100644 --- a/src/settings/components/index.jsx +++ b/src/settings/components/index.jsx @@ -1,11 +1,11 @@ import './site.scss'; -import { h, Component } from 'preact'; -import { connect } from 'preact-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 React from 'react'; +import { connect } from 'react-redux'; +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'; @@ -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()); } @@ -25,6 +25,7 @@ class SettingsComponent extends Component { <KeymapsForm value={form.keymaps} onChange={value => this.bindForm('keymaps', value)} + onBlur={this.save.bind(this)} /> </fieldset> <fieldset> @@ -32,6 +33,7 @@ class SettingsComponent extends Component { <SearchForm value={form.search} onChange={value => this.bindForm('search', value)} + onBlur={this.save.bind(this)} /> </fieldset> <fieldset> @@ -39,6 +41,7 @@ class SettingsComponent extends Component { <BlacklistForm value={form.blacklist} onChange={value => this.bindForm('blacklist', value)} + onBlur={this.save.bind(this)} /> </fieldset> <fieldset> @@ -47,6 +50,7 @@ class SettingsComponent extends Component { types={properties.types} value={form.properties} onChange={value => this.bindForm('properties', value)} + onBlur={this.save.bind(this)} /> </fieldset> </div>; @@ -61,6 +65,7 @@ class SettingsComponent extends Component { spellCheck='false' error={error} onChange={this.bindJson.bind(this)} + onBlur={this.save.bind(this)} value={json} /> </div>; @@ -109,7 +114,7 @@ class SettingsComponent extends Component { form: { ...this.props.form }, }; settings.form[name] = value; - this.props.dispatch(settingActions.save(settings)); + this.props.dispatch(settingActions.set(settings)); } bindJson(e) { @@ -118,7 +123,7 @@ class SettingsComponent extends Component { json: e.target.value, form: this.props.form, }; - this.props.dispatch(settingActions.save(settings)); + this.props.dispatch(settingActions.set(settings)); } bindSource(e) { @@ -135,8 +140,10 @@ class SettingsComponent extends Component { } this.props.dispatch(settingActions.switchToForm(this.props.json)); } + } - let settings = this.context.store.getState(); + save() { + let settings = this.props.store.getState(); this.props.dispatch(settingActions.save(settings)); } } diff --git a/src/settings/components/ui/add-button.jsx b/src/settings/components/ui/AddButton.jsx index 79292d8..185a03b 100644 --- a/src/settings/components/ui/add-button.jsx +++ b/src/settings/components/ui/AddButton.jsx @@ -1,7 +1,7 @@ -import './add-button.scss'; -import { h, Component } from 'preact'; +import './AddButton.scss'; +import React from 'react'; -class AddButton extends Component { +class AddButton extends React.Component { render() { return <input className='ui-add-button' type='button' value='✚' diff --git a/src/settings/components/ui/add-button.scss b/src/settings/components/ui/AddButton.scss index beb5688..beb5688 100644 --- a/src/settings/components/ui/add-button.scss +++ b/src/settings/components/ui/AddButton.scss diff --git a/src/settings/components/ui/delete-button.jsx b/src/settings/components/ui/DeleteButton.jsx index 8077a76..75811cd 100644 --- a/src/settings/components/ui/delete-button.jsx +++ b/src/settings/components/ui/DeleteButton.jsx @@ -1,7 +1,7 @@ -import './delete-button.scss'; -import { h, Component } from 'preact'; +import './DeleteButton.scss'; +import React from 'react'; -class DeleteButton extends Component { +class DeleteButton extends React.Component { render() { return <input className='ui-delete-button' type='button' value='✖' diff --git a/src/settings/components/ui/delete-button.scss b/src/settings/components/ui/DeleteButton.scss index 5932a72..5932a72 100644 --- a/src/settings/components/ui/delete-button.scss +++ b/src/settings/components/ui/DeleteButton.scss diff --git a/src/settings/components/ui/input.jsx b/src/settings/components/ui/Input.jsx index e99dbc7..13a246b 100644 --- a/src/settings/components/ui/input.jsx +++ b/src/settings/components/ui/Input.jsx @@ -1,7 +1,8 @@ -import { h, Component } from 'preact'; -import './input.scss'; +import React from 'react'; +import PropTypes from 'prop-types'; +import './Input.scss'; -class Input extends Component { +class Input extends React.Component { renderText(props) { let inputClassName = props.error ? 'input-error' : ''; @@ -49,4 +50,11 @@ class Input extends Component { } } +Input.propTypes = { + type: PropTypes.string, + error: PropTypes.string, + label: PropTypes.string, + value: PropTypes.string, +}; + export default Input; diff --git a/src/settings/components/ui/input.scss b/src/settings/components/ui/Input.scss index ad4daf8..ad4daf8 100644 --- a/src/settings/components/ui/input.scss +++ b/src/settings/components/ui/Input.scss diff --git a/src/settings/index.jsx b/src/settings/index.jsx index 8097d31..6aec7a0 100644 --- a/src/settings/index.jsx +++ b/src/settings/index.jsx @@ -1,7 +1,8 @@ -import { h, render } from 'preact'; +import React from 'react'; +import ReactDOM from 'react-dom'; import SettingsComponent from './components'; import reducer from './reducers/setting'; -import { Provider } from 'preact-redux'; +import { Provider } from 'react-redux'; import promise from 'redux-promise'; import { createStore, applyMiddleware } from 'redux'; @@ -12,9 +13,9 @@ const store = createStore( document.addEventListener('DOMContentLoaded', () => { let wrapper = document.getElementById('vimvixen-settings'); - render( + ReactDOM.render( <Provider store={store}> - <SettingsComponent /> + <SettingsComponent store={store} /> </Provider>, wrapper ); diff --git a/src/settings/components/form/keymaps-form.jsx b/src/settings/keymaps.js index ca51c96..ccfc74c 100644 --- a/src/settings/components/form/keymaps-form.jsx +++ b/src/settings/keymaps.js @@ -1,8 +1,4 @@ -import './keymaps-form.scss'; -import { h, Component } from 'preact'; -import Input from '../ui/input'; - -const KeyMapFields = [ +const fields = [ [ ['scroll.vertically?{"count":1}', 'Scroll down'], ['scroll.vertically?{"count":-1}', 'Scroll up'], @@ -70,49 +66,9 @@ const KeyMapFields = [ ] ]; -const AllowdOps = [].concat(...KeyMapFields.map(group => group.map(e => e[0]))); - -class KeymapsForm extends Component { - - render() { - let values = this.props.value; - if (!values) { - values = {}; - } - return <div className='form-keymaps-form'> - { - KeyMapFields.map((group, index) => { - return <div key={index} className='form-keymaps-form-field-group'> - { - group.map((field) => { - let name = field[0]; - let label = field[1]; - let value = values[name]; - return <Input - type='text' id={name} name={name} key={name} - label={label} value={value} - onChange={this.bindValue.bind(this)} - />; - }) - } - </div>; - }) - } - </div>; - } - - 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; +const allowedOps = [].concat(...fields.map(group => group.map(e => e[0]))); -export default KeymapsForm; +export default { + fields, + allowedOps, +}; |