Adding URL handling

This commit is contained in:
Jeff Avallone 2018-02-19 17:29:08 -05:00
parent 50d05c423d
commit aa278fb193
7 changed files with 111 additions and 18 deletions

View File

@ -160,6 +160,7 @@
"style-loader": "^0.20.1",
"svg-react-loader": "^0.4.5",
"uglifyjs-webpack-plugin": "^1.1.8",
"url-search-params": "^0.10.0",
"webpack": "^3.10.0",
"webpack-merge": "^4.1.1",
"webpack-node-externals": "^1.6.0",

View File

@ -5,7 +5,6 @@ exports[`App rendering 1`] = `
<Translate(Form)
downloadUrls={Array []}
onSubmit={[Function]}
permalinkUrl="#permalink"
syntaxes={
Object {
"js": "JavaScript",

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import URLSearchParams from 'url-search-params';
import style from './style.css';
@ -14,6 +15,15 @@ class App extends React.PureComponent {
syntaxes
}
componentDidMount() {
window.addEventListener('hashchange', this.handleHashChange);
this.handleHashChange();
}
componentWillUnmount() {
window.removeEventListener('hashchange', this.handleHashChange);
}
setSvgUrl(element) {
try {
const type = 'image/svg+xml';
@ -68,9 +78,40 @@ class App extends React.PureComponent {
}
handleSubmit = ({expr, syntax}) => {
if (expr) {
const params = new URLSearchParams({ syntax, expr });
document.location.hash = params.toString();
}
}
handleHashChange = () => {
const query = document.location.hash.slice(1);
const params = new URLSearchParams(query);
const { expr, syntax } = (() => {
if (params.get('syntax')) {
return {
syntax: params.get('syntax'),
expr: params.get('expr')
};
} else {
// Assuming old-style URL
return {
syntax: 'js',
expr: query
};
}
})();
if (!expr) {
return;
}
console.log(syntax, expr); // eslint-disable-line no-console
this.setState({
image: demoImage
image: demoImage,
permalinkUrl: document.location.toString(),
syntax,
expr
}, async () => {
await this.image.doReflow();
this.setSvgUrl(this.image.svg);
@ -81,7 +122,7 @@ class App extends React.PureComponent {
imageRef = image => this.image = image
render() {
const { svgUrl, pngUrl, syntaxes, image } = this.state;
const { svgUrl, pngUrl, permalinkUrl, syntax, expr, syntaxes, image } = this.state;
const downloadUrls = [
svgUrl,
pngUrl
@ -91,7 +132,9 @@ class App extends React.PureComponent {
<Form
syntaxes={ syntaxes }
downloadUrls={ downloadUrls }
permalinkUrl="#permalink"
permalinkUrl={ permalinkUrl }
syntax={ syntax }
expr={ expr }
onSubmit={ this.handleSubmit }/>
<Message type="error" heading="Sample Error">
<p>Sample error message</p>

View File

@ -9,6 +9,8 @@ exports[`Form rendering 1`] = `
>
<textarea
autoFocus={true}
name="expr"
onChange={[Function]}
onKeyPress={[Function]}
placeholder="translate(Enter regular expression to display)"
/>
@ -22,7 +24,11 @@ exports[`Form rendering 1`] = `
<div
className="select"
>
<select>
<select
name="syntax"
onChange={[Function]}
value="js"
>
<option
key="js"
value="js"
@ -54,6 +60,8 @@ exports[`Form rendering with download URLs 1`] = `
>
<textarea
autoFocus={true}
name="expr"
onChange={[Function]}
onKeyPress={[Function]}
placeholder="translate(Enter regular expression to display)"
/>
@ -67,7 +75,11 @@ exports[`Form rendering with download URLs 1`] = `
<div
className="select"
>
<select>
<select
name="syntax"
onChange={[Function]}
value="js"
>
<option
key="js"
value="js"
@ -124,6 +136,8 @@ exports[`Form rendering with permalink URL 1`] = `
>
<textarea
autoFocus={true}
name="expr"
onChange={[Function]}
onKeyPress={[Function]}
placeholder="translate(Enter regular expression to display)"
/>
@ -137,7 +151,11 @@ exports[`Form rendering with permalink URL 1`] = `
<div
className="select"
>
<select>
<select
name="syntax"
onChange={[Function]}
value="js"
>
<option
key="js"
value="js"

View File

@ -8,12 +8,34 @@ import ExpandIcon from 'feather-icons/dist/icons/chevrons-down.svg';
import style from './style.css';
class Form extends React.Component {
class Form extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
syntax: props.syntax || Object.keys(props.syntaxes)[0],
expr: props.expr
};
}
componentWillReceiveProps(next) {
if (this.props.expr !== next.expr) {
this.setState({
expr: next.expr
});
}
if (this.props.syntax !== next.syntax) {
this.setState({
syntax: next.syntax
});
}
}
handleSubmit = event => {
event.preventDefault();
this.props.onSubmit.call(this, {
expr: this.textarea.value,
syntax: this.syntax.value
expr: this.state.expr,
syntax: this.state.syntax
});
}
@ -23,9 +45,7 @@ class Form extends React.Component {
}
}
textareaRef = textarea => this.textarea = textarea
syntaxRef = syntax => this.syntax = syntax
handleChange = event => this.setState({ [event.target.name]: event.target.value })
permalinkAction() {
const { permalinkUrl } = this.props;
@ -55,17 +75,23 @@ class Form extends React.Component {
render() {
const { syntaxes, t } = this.props;
const { expr, syntax } = this.state;
return <div className={ style.form }>
<form onSubmit={ this.handleSubmit }>
<textarea
ref={ this.textareaRef }
name="expr"
value={ expr }
onKeyPress={ this.handleKeyPress }
onChange={ this.handleChange }
autoFocus
placeholder={ t('Enter regular expression to display') }></textarea>
<button type="submit"><Trans>Display</Trans></button>
<div className={ style.select }>
<select ref={ this.syntaxRef }>
<select
name="syntax"
value={ syntax }
onChange={ this.handleChange }>
{ Object.keys(syntaxes).map(id => (
<option value={ id } key={ id }>{ syntaxes[id] }</option>
)) }
@ -83,6 +109,8 @@ class Form extends React.Component {
}
Form.propTypes = {
expr: PropTypes.string,
syntax: PropTypes.string,
syntaxes: PropTypes.object,
onSubmit: PropTypes.func,
permalinkUrl: PropTypes.string,

View File

@ -50,13 +50,13 @@ describe('Form', () => {
const onSubmit = jest.fn();
const component = build({ onSubmit });
const eventObj = { preventDefault: jest.fn() };
component.find(Form).instance().textarea.value = 'Test textarea value';
component.find(Form).instance().setState({ syntax: 'test', expr: 'Test expression' });
component.find('form').simulate('submit', eventObj);
expect(eventObj.preventDefault).toHaveBeenCalled();
expect(onSubmit).toHaveBeenCalledWith({
expr: 'Test textarea value',
syntax: 'js'
expr: 'Test expression',
syntax: 'test'
});
});

View File

@ -8132,6 +8132,10 @@ url-regex@^3.0.0:
dependencies:
ip-regex "^1.0.1"
url-search-params@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/url-search-params/-/url-search-params-0.10.0.tgz#d428c1fa9d78d5c5a3feb634147873890f4adcf0"
url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"