diff options
Diffstat (limited to 'src/settings/components')
-rw-r--r-- | src/settings/components/index.jsx | 91 | ||||
-rw-r--r-- | src/settings/components/setting.js | 45 | ||||
-rw-r--r-- | src/settings/components/site.scss | 8 |
3 files changed, 99 insertions, 45 deletions
diff --git a/src/settings/components/index.jsx b/src/settings/components/index.jsx new file mode 100644 index 0000000..4418942 --- /dev/null +++ b/src/settings/components/index.jsx @@ -0,0 +1,91 @@ +import './site.scss'; +import React from 'react'; +import PropTypes from 'prop-types'; +import * as settingActions from 'settings/actions/setting'; +import * as validator from 'shared/validators/setting'; + +class SettingsComponent extends React.Component { + constructor(props, context) { + super(props, context); + + this.state = { + settings: { + json: '', + } + }; + this.context.store.subscribe(this.stateChanged.bind(this)); + } + + componentDidMount() { + this.context.store.dispatch(settingActions.load()); + } + + stateChanged() { + let settings = this.context.store.getState(); + this.setState({ + settings: { + source: settings.source, + json: settings.json, + } + }); + } + + render() { + return ( + <div> + <h1>Configure Vim-Vixen</h1> + <form className='vimvixen-settings-form'> + + <p>Load settings from:</p> + <input type='radio' id='setting-source-json' + name='source' + value='json' + onChange={this.bindAndSave.bind(this)} + checked={this.state.settings.source === 'json'} /> + <label htmlFor='settings-source-json'>JSON</label> + + <textarea name='json' spellCheck='false' + onInput={this.validate.bind(this)} + onChange={this.bindValue.bind(this)} + onBlur={this.bindAndSave.bind(this)} + value={this.state.settings.json} /> + </form> + </div> + ); + } + + validate(e) { + try { + let settings = JSON.parse(e.target.value); + validator.validate(settings); + e.target.setCustomValidity(''); + } catch (err) { + e.target.setCustomValidity(err.message); + } + } + + bindValue(e) { + let nextSettings = Object.assign({}, this.state.settings); + nextSettings[e.target.name] = e.target.value; + + this.setState({ settings: nextSettings }); + } + + bindAndSave(e) { + this.bindValue(e); + + try { + let json = this.state.settings.json; + validator.validate(JSON.parse(json)); + this.context.store.dispatch(settingActions.save(this.state.settings)); + } catch (err) { + // error already shown + } + } +} + +SettingsComponent.contextTypes = { + store: PropTypes.any, +}; + +export default SettingsComponent; diff --git a/src/settings/components/setting.js b/src/settings/components/setting.js deleted file mode 100644 index 14482a3..0000000 --- a/src/settings/components/setting.js +++ /dev/null @@ -1,45 +0,0 @@ -import * as settingActions from 'settings/actions/setting'; -import { validate } from 'shared/validators/setting'; - -export default class SettingComponent { - constructor(wrapper, store) { - this.wrapper = wrapper; - this.store = store; - - let doc = wrapper.ownerDocument; - let form = doc.getElementById('vimvixen-settings-form'); - form.addEventListener('submit', this.onSubmit.bind(this)); - - let plainJson = form.elements['plain-json']; - plainJson.addEventListener('input', this.onPlainJsonChanged.bind(this)); - - store.dispatch(settingActions.load()); - } - - onSubmit(e) { - let settings = { - json: e.target.elements['plain-json'].value, - }; - this.store.dispatch(settingActions.save(settings)); - e.preventDefault(); - } - - onPlainJsonChanged(e) { - try { - let settings = JSON.parse(e.target.value); - validate(settings); - e.target.setCustomValidity(''); - } catch (err) { - e.target.setCustomValidity(err.message); - } - } - - update() { - let { settings } = this.store.getState(); - - let doc = this.wrapper.ownerDocument; - let form = doc.getElementById('vimvixen-settings-form'); - let plainJsonInput = form.elements['plain-json']; - plainJsonInput.value = settings.json; - } -} diff --git a/src/settings/components/site.scss b/src/settings/components/site.scss new file mode 100644 index 0000000..fae9c39 --- /dev/null +++ b/src/settings/components/site.scss @@ -0,0 +1,8 @@ +.vimvixen-settings-form { + textarea[name=json] { + font-family: monospace; + width: 100%; + min-height: 64ex; + resize: vertical; + } +} |