Adding URL handling
This commit is contained in:
parent
50d05c423d
commit
aa278fb193
@ -160,6 +160,7 @@
|
|||||||
"style-loader": "^0.20.1",
|
"style-loader": "^0.20.1",
|
||||||
"svg-react-loader": "^0.4.5",
|
"svg-react-loader": "^0.4.5",
|
||||||
"uglifyjs-webpack-plugin": "^1.1.8",
|
"uglifyjs-webpack-plugin": "^1.1.8",
|
||||||
|
"url-search-params": "^0.10.0",
|
||||||
"webpack": "^3.10.0",
|
"webpack": "^3.10.0",
|
||||||
"webpack-merge": "^4.1.1",
|
"webpack-merge": "^4.1.1",
|
||||||
"webpack-node-externals": "^1.6.0",
|
"webpack-node-externals": "^1.6.0",
|
||||||
|
@ -5,7 +5,6 @@ exports[`App rendering 1`] = `
|
|||||||
<Translate(Form)
|
<Translate(Form)
|
||||||
downloadUrls={Array []}
|
downloadUrls={Array []}
|
||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
permalinkUrl="#permalink"
|
|
||||||
syntaxes={
|
syntaxes={
|
||||||
Object {
|
Object {
|
||||||
"js": "JavaScript",
|
"js": "JavaScript",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { translate } from 'react-i18next';
|
import { translate } from 'react-i18next';
|
||||||
|
import URLSearchParams from 'url-search-params';
|
||||||
|
|
||||||
import style from './style.css';
|
import style from './style.css';
|
||||||
|
|
||||||
@ -14,6 +15,15 @@ class App extends React.PureComponent {
|
|||||||
syntaxes
|
syntaxes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.addEventListener('hashchange', this.handleHashChange);
|
||||||
|
this.handleHashChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener('hashchange', this.handleHashChange);
|
||||||
|
}
|
||||||
|
|
||||||
setSvgUrl(element) {
|
setSvgUrl(element) {
|
||||||
try {
|
try {
|
||||||
const type = 'image/svg+xml';
|
const type = 'image/svg+xml';
|
||||||
@ -68,9 +78,40 @@ class App extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit = ({expr, syntax}) => {
|
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
|
console.log(syntax, expr); // eslint-disable-line no-console
|
||||||
this.setState({
|
this.setState({
|
||||||
image: demoImage
|
image: demoImage,
|
||||||
|
permalinkUrl: document.location.toString(),
|
||||||
|
syntax,
|
||||||
|
expr
|
||||||
}, async () => {
|
}, async () => {
|
||||||
await this.image.doReflow();
|
await this.image.doReflow();
|
||||||
this.setSvgUrl(this.image.svg);
|
this.setSvgUrl(this.image.svg);
|
||||||
@ -81,7 +122,7 @@ class App extends React.PureComponent {
|
|||||||
imageRef = image => this.image = image
|
imageRef = image => this.image = image
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { svgUrl, pngUrl, syntaxes, image } = this.state;
|
const { svgUrl, pngUrl, permalinkUrl, syntax, expr, syntaxes, image } = this.state;
|
||||||
const downloadUrls = [
|
const downloadUrls = [
|
||||||
svgUrl,
|
svgUrl,
|
||||||
pngUrl
|
pngUrl
|
||||||
@ -91,7 +132,9 @@ class App extends React.PureComponent {
|
|||||||
<Form
|
<Form
|
||||||
syntaxes={ syntaxes }
|
syntaxes={ syntaxes }
|
||||||
downloadUrls={ downloadUrls }
|
downloadUrls={ downloadUrls }
|
||||||
permalinkUrl="#permalink"
|
permalinkUrl={ permalinkUrl }
|
||||||
|
syntax={ syntax }
|
||||||
|
expr={ expr }
|
||||||
onSubmit={ this.handleSubmit }/>
|
onSubmit={ this.handleSubmit }/>
|
||||||
<Message type="error" heading="Sample Error">
|
<Message type="error" heading="Sample Error">
|
||||||
<p>Sample error message</p>
|
<p>Sample error message</p>
|
||||||
|
@ -9,6 +9,8 @@ exports[`Form rendering 1`] = `
|
|||||||
>
|
>
|
||||||
<textarea
|
<textarea
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
|
name="expr"
|
||||||
|
onChange={[Function]}
|
||||||
onKeyPress={[Function]}
|
onKeyPress={[Function]}
|
||||||
placeholder="translate(Enter regular expression to display)"
|
placeholder="translate(Enter regular expression to display)"
|
||||||
/>
|
/>
|
||||||
@ -22,7 +24,11 @@ exports[`Form rendering 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="select"
|
className="select"
|
||||||
>
|
>
|
||||||
<select>
|
<select
|
||||||
|
name="syntax"
|
||||||
|
onChange={[Function]}
|
||||||
|
value="js"
|
||||||
|
>
|
||||||
<option
|
<option
|
||||||
key="js"
|
key="js"
|
||||||
value="js"
|
value="js"
|
||||||
@ -54,6 +60,8 @@ exports[`Form rendering with download URLs 1`] = `
|
|||||||
>
|
>
|
||||||
<textarea
|
<textarea
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
|
name="expr"
|
||||||
|
onChange={[Function]}
|
||||||
onKeyPress={[Function]}
|
onKeyPress={[Function]}
|
||||||
placeholder="translate(Enter regular expression to display)"
|
placeholder="translate(Enter regular expression to display)"
|
||||||
/>
|
/>
|
||||||
@ -67,7 +75,11 @@ exports[`Form rendering with download URLs 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="select"
|
className="select"
|
||||||
>
|
>
|
||||||
<select>
|
<select
|
||||||
|
name="syntax"
|
||||||
|
onChange={[Function]}
|
||||||
|
value="js"
|
||||||
|
>
|
||||||
<option
|
<option
|
||||||
key="js"
|
key="js"
|
||||||
value="js"
|
value="js"
|
||||||
@ -124,6 +136,8 @@ exports[`Form rendering with permalink URL 1`] = `
|
|||||||
>
|
>
|
||||||
<textarea
|
<textarea
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
|
name="expr"
|
||||||
|
onChange={[Function]}
|
||||||
onKeyPress={[Function]}
|
onKeyPress={[Function]}
|
||||||
placeholder="translate(Enter regular expression to display)"
|
placeholder="translate(Enter regular expression to display)"
|
||||||
/>
|
/>
|
||||||
@ -137,7 +151,11 @@ exports[`Form rendering with permalink URL 1`] = `
|
|||||||
<div
|
<div
|
||||||
className="select"
|
className="select"
|
||||||
>
|
>
|
||||||
<select>
|
<select
|
||||||
|
name="syntax"
|
||||||
|
onChange={[Function]}
|
||||||
|
value="js"
|
||||||
|
>
|
||||||
<option
|
<option
|
||||||
key="js"
|
key="js"
|
||||||
value="js"
|
value="js"
|
||||||
|
@ -8,12 +8,34 @@ import ExpandIcon from 'feather-icons/dist/icons/chevrons-down.svg';
|
|||||||
|
|
||||||
import style from './style.css';
|
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 => {
|
handleSubmit = event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.props.onSubmit.call(this, {
|
this.props.onSubmit.call(this, {
|
||||||
expr: this.textarea.value,
|
expr: this.state.expr,
|
||||||
syntax: this.syntax.value
|
syntax: this.state.syntax
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,9 +45,7 @@ class Form extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
textareaRef = textarea => this.textarea = textarea
|
handleChange = event => this.setState({ [event.target.name]: event.target.value })
|
||||||
|
|
||||||
syntaxRef = syntax => this.syntax = syntax
|
|
||||||
|
|
||||||
permalinkAction() {
|
permalinkAction() {
|
||||||
const { permalinkUrl } = this.props;
|
const { permalinkUrl } = this.props;
|
||||||
@ -55,17 +75,23 @@ class Form extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { syntaxes, t } = this.props;
|
const { syntaxes, t } = this.props;
|
||||||
|
const { expr, syntax } = this.state;
|
||||||
|
|
||||||
return <div className={ style.form }>
|
return <div className={ style.form }>
|
||||||
<form onSubmit={ this.handleSubmit }>
|
<form onSubmit={ this.handleSubmit }>
|
||||||
<textarea
|
<textarea
|
||||||
ref={ this.textareaRef }
|
name="expr"
|
||||||
|
value={ expr }
|
||||||
onKeyPress={ this.handleKeyPress }
|
onKeyPress={ this.handleKeyPress }
|
||||||
|
onChange={ this.handleChange }
|
||||||
autoFocus
|
autoFocus
|
||||||
placeholder={ t('Enter regular expression to display') }></textarea>
|
placeholder={ t('Enter regular expression to display') }></textarea>
|
||||||
<button type="submit"><Trans>Display</Trans></button>
|
<button type="submit"><Trans>Display</Trans></button>
|
||||||
<div className={ style.select }>
|
<div className={ style.select }>
|
||||||
<select ref={ this.syntaxRef }>
|
<select
|
||||||
|
name="syntax"
|
||||||
|
value={ syntax }
|
||||||
|
onChange={ this.handleChange }>
|
||||||
{ Object.keys(syntaxes).map(id => (
|
{ Object.keys(syntaxes).map(id => (
|
||||||
<option value={ id } key={ id }>{ syntaxes[id] }</option>
|
<option value={ id } key={ id }>{ syntaxes[id] }</option>
|
||||||
)) }
|
)) }
|
||||||
@ -83,6 +109,8 @@ class Form extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Form.propTypes = {
|
Form.propTypes = {
|
||||||
|
expr: PropTypes.string,
|
||||||
|
syntax: PropTypes.string,
|
||||||
syntaxes: PropTypes.object,
|
syntaxes: PropTypes.object,
|
||||||
onSubmit: PropTypes.func,
|
onSubmit: PropTypes.func,
|
||||||
permalinkUrl: PropTypes.string,
|
permalinkUrl: PropTypes.string,
|
||||||
|
@ -50,13 +50,13 @@ describe('Form', () => {
|
|||||||
const onSubmit = jest.fn();
|
const onSubmit = jest.fn();
|
||||||
const component = build({ onSubmit });
|
const component = build({ onSubmit });
|
||||||
const eventObj = { preventDefault: jest.fn() };
|
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);
|
component.find('form').simulate('submit', eventObj);
|
||||||
|
|
||||||
expect(eventObj.preventDefault).toHaveBeenCalled();
|
expect(eventObj.preventDefault).toHaveBeenCalled();
|
||||||
expect(onSubmit).toHaveBeenCalledWith({
|
expect(onSubmit).toHaveBeenCalledWith({
|
||||||
expr: 'Test textarea value',
|
expr: 'Test expression',
|
||||||
syntax: 'js'
|
syntax: 'test'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -8132,6 +8132,10 @@ url-regex@^3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ip-regex "^1.0.1"
|
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:
|
url@^0.11.0:
|
||||||
version "0.11.0"
|
version "0.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
||||||
|
Loading…
Reference in New Issue
Block a user