178 lines
5.3 KiB
JavaScript
178 lines
5.3 KiB
JavaScript
|
|
import React, { Component } from 'react';
|
|
import axios from 'axios';
|
|
|
|
import Container from 'react-bootstrap/Container';
|
|
import Row from 'react-bootstrap/Row';
|
|
import Col from 'react-bootstrap/Col';
|
|
|
|
import Header from "./Header";
|
|
import Tabs from "./preg/Tabs";
|
|
import Opts from "./preg/Opts";
|
|
import Fields from "./preg/Fields";
|
|
import Return from "./preg/Return";
|
|
import Code from "./preg/Code";
|
|
import Output from "./preg/Output";
|
|
import Footer from "./Footer";
|
|
import Help from "./preg/Help";
|
|
|
|
export default class App extends Component {
|
|
constructor(props) {
|
|
super(props)
|
|
|
|
this.state = {
|
|
method: 'preg_match',
|
|
pattern: '',
|
|
replacement: '',
|
|
subject: '',
|
|
offset: null,
|
|
limit: null,
|
|
delimiter: null,
|
|
PREG_OFFSET_CAPTURE: false,
|
|
PREG_UNMATCHED_AS_NULL: false,
|
|
PREG_SET_ORDER: false,
|
|
PREG_SPLIT_NO_EMPTY: false,
|
|
PREG_SPLIT_DELIM_CAPTURE: false,
|
|
PREG_SPLIT_OFFSET_CAPTURE: false,
|
|
response: {},
|
|
help: false
|
|
}
|
|
|
|
this.timer = null
|
|
|
|
this.maps = {
|
|
'preg_match': {
|
|
'fields': ['pattern', 'subject'],
|
|
'opts': ['PREG_OFFSET_CAPTURE', 'PREG_UNMATCHED_AS_NULL', 'offset']
|
|
},
|
|
'preg_match_all': {
|
|
'fields': ['pattern', 'subject'],
|
|
'opts': ['PREG_PATTERN_ORDER', 'PREG_SET_ORDER', 'PREG_OFFSET_CAPTURE', 'PREG_UNMATCHED_AS_NULL', 'offset']
|
|
},
|
|
'preg_split': {
|
|
'fields': ['pattern', 'subject'],
|
|
'opts': ['PREG_SPLIT_NO_EMPTY', 'PREG_SPLIT_DELIM_CAPTURE', 'PREG_SPLIT_OFFSET_CAPTURE', 'limit']
|
|
},
|
|
'preg_replace': {
|
|
'fields': ['pattern', 'subject', 'replacement'],
|
|
'opts': ['limit']
|
|
},
|
|
'preg_quote': {
|
|
'fields': ['pattern'],
|
|
'opts': ['delimeter']
|
|
}
|
|
}
|
|
}
|
|
|
|
componentDidMount() {
|
|
window.addEventListener("hashchange", this.hashChange, false)
|
|
this.hashChange()
|
|
}
|
|
|
|
hashChange = () => {
|
|
const hash = window.location.hash.replace(/^#/, '')
|
|
|
|
if (hash && hash !== 'close' && hash !== 'help' && hash !== this.state.response.hash) {
|
|
axios.get('/api/preg', { params: { hash } }).then((res) => {
|
|
this.setState({ ...res.data, response: {} }, () => {
|
|
this.api()
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
methodSelect = (method) => {
|
|
this.setState({method}, this.api)
|
|
}
|
|
|
|
handleInputChange = (event) => {
|
|
const target = event.target
|
|
const value = (target.type === 'checkbox')?
|
|
target.checked:
|
|
(target.type === 'number'?
|
|
parseInt(target.value):
|
|
target.value)
|
|
const name = target.name
|
|
|
|
this.setState({ [name]: value }, this.delay)
|
|
}
|
|
|
|
api = () => {
|
|
const { response, help, ...state } = this.state
|
|
|
|
axios.post('/api/preg', state).then((res) => {
|
|
this.setState({ response: res.data }, () => {
|
|
if ('hash' in res.data) {
|
|
window.location.hash = '#'+res.data.hash;
|
|
}
|
|
})
|
|
}).catch((error) => {
|
|
//console.log(error.response)
|
|
this.setState({ response: {
|
|
fatal: (error.response? error.response.data.fatal: error.message)
|
|
} }, () => {
|
|
window.history.replaceState(null, null, ' ');
|
|
})
|
|
});
|
|
}
|
|
|
|
delay = () => {
|
|
clearTimeout(this.timer)
|
|
this.timer = setTimeout(this.api, 200)
|
|
}
|
|
|
|
showHelp = (show) => {
|
|
this.setState({ help: show })
|
|
}
|
|
|
|
render() {
|
|
const { method, pattern, replacement, subject, response, help, ...state } = this.state
|
|
const maps = this.maps[method]
|
|
|
|
return (
|
|
<>
|
|
<Header method={method} hash={response.hash? window.location.origin+"/#"+response.hash: null} onClick={() => this.showHelp(true)} />
|
|
|
|
<Container>
|
|
<Row className="mt-3 mb-3">
|
|
<Col>
|
|
<Tabs method={method} functions={Object.keys(this.maps)} onChange={this.methodSelect} />
|
|
</Col>
|
|
</Row>
|
|
|
|
<Fields method={method} fields={maps.fields} pattern={pattern} replacement={replacement} subject={subject} onChange={this.handleInputChange} />
|
|
|
|
<div className="separator">options</div>
|
|
<Opts method={method} opts={maps.opts} {...state} onChange={this.handleInputChange} />
|
|
|
|
<Row className="mt-3">
|
|
<Col xs="3" sm="2">
|
|
<div className="separator">return</div>
|
|
<Return response={response} />
|
|
</Col>
|
|
<Col>
|
|
<div className="separator">snippet</div>
|
|
<Code response={response} />
|
|
</Col>
|
|
</Row>
|
|
|
|
<Row className="mt-3">
|
|
<Col>
|
|
<div className="separator">$matches or result</div>
|
|
<Output response={response} />
|
|
</Col>
|
|
</Row>
|
|
|
|
<Row className="mt-3 text-end">
|
|
<Col>
|
|
<Footer />
|
|
</Col>
|
|
</Row>
|
|
</Container>
|
|
|
|
<Help show={help} onHide={() => this.showHelp(false)} />
|
|
</>
|
|
);
|
|
}
|
|
}
|