Adding URL handling
This commit is contained in:
@@ -5,7 +5,6 @@ exports[`App rendering 1`] = `
|
||||
<Translate(Form)
|
||||
downloadUrls={Array []}
|
||||
onSubmit={[Function]}
|
||||
permalinkUrl="#permalink"
|
||||
syntaxes={
|
||||
Object {
|
||||
"js": "JavaScript",
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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'
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user