Clean-Up #3314
This commit is contained in:
parent
97378daee5
commit
29442673f8
@ -15,223 +15,13 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { MenuItem } from 'material-ui';
|
|
||||||
import { range } from 'lodash';
|
|
||||||
|
|
||||||
import IconButton from 'material-ui/IconButton';
|
import { AddressSelect, Form, Input, TypedInput } from '../../../ui';
|
||||||
import AddIcon from 'material-ui/svg-icons/content/add';
|
|
||||||
import RemoveIcon from 'material-ui/svg-icons/content/remove';
|
|
||||||
|
|
||||||
import { AddressSelect, Form, Input, InputAddressSelect, Select } from '../../../ui';
|
|
||||||
import { validateAbi } from '../../../util/validation';
|
import { validateAbi } from '../../../util/validation';
|
||||||
|
import { parseAbiType } from '../../../util/abi';
|
||||||
|
|
||||||
import styles from '../deployContract.css';
|
import styles from '../deployContract.css';
|
||||||
|
|
||||||
class TypedInput extends Component {
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
onChange: PropTypes.func.isRequired,
|
|
||||||
accounts: PropTypes.object.isRequired,
|
|
||||||
param: PropTypes.object.isRequired,
|
|
||||||
|
|
||||||
error: PropTypes.any,
|
|
||||||
value: PropTypes.any,
|
|
||||||
label: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { param } = this.props;
|
|
||||||
const { type } = param;
|
|
||||||
|
|
||||||
if (type === ARRAY_TYPE) {
|
|
||||||
const { accounts, label, value = param.default } = this.props;
|
|
||||||
const { subtype, length } = param;
|
|
||||||
|
|
||||||
const fixedLength = !!length;
|
|
||||||
|
|
||||||
const inputs = range(length || value.length).map((_, index) => {
|
|
||||||
const onChange = (inputValue) => {
|
|
||||||
const newValues = [].concat(this.props.value);
|
|
||||||
newValues[index] = inputValue;
|
|
||||||
this.props.onChange(newValues);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TypedInput
|
|
||||||
key={ `${subtype.type}_${index}` }
|
|
||||||
onChange={ onChange }
|
|
||||||
accounts={ accounts }
|
|
||||||
param={ subtype }
|
|
||||||
value={ value[index] }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={ styles.inputs }>
|
|
||||||
<label>{ label }</label>
|
|
||||||
{ fixedLength ? null : this.renderLength() }
|
|
||||||
{ inputs }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.renderType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderLength () {
|
|
||||||
const style = {
|
|
||||||
width: 16,
|
|
||||||
height: 16
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<IconButton
|
|
||||||
iconStyle={ style }
|
|
||||||
style={ style }
|
|
||||||
onClick={ this.onAddField }
|
|
||||||
>
|
|
||||||
<AddIcon />
|
|
||||||
</IconButton>
|
|
||||||
|
|
||||||
<IconButton
|
|
||||||
iconStyle={ style }
|
|
||||||
style={ style }
|
|
||||||
onClick={ this.onRemoveField }
|
|
||||||
>
|
|
||||||
<RemoveIcon />
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderType (type) {
|
|
||||||
if (type === ADDRESS_TYPE) {
|
|
||||||
return this.renderAddress();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === BOOL_TYPE) {
|
|
||||||
return this.renderBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === STRING_TYPE) {
|
|
||||||
return this.renderDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === BYTES_TYPE) {
|
|
||||||
return this.renderDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === INT_TYPE) {
|
|
||||||
return this.renderNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === FIXED_TYPE) {
|
|
||||||
return this.renderNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.renderDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderNumber () {
|
|
||||||
const { label, value, error, param } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Input
|
|
||||||
label={ label }
|
|
||||||
value={ value }
|
|
||||||
error={ error }
|
|
||||||
onSubmit={ this.onSubmit }
|
|
||||||
type='number'
|
|
||||||
min={ param.signed ? null : 0 }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderDefault () {
|
|
||||||
const { label, value, error } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Input
|
|
||||||
label={ label }
|
|
||||||
value={ value }
|
|
||||||
error={ error }
|
|
||||||
onSubmit={ this.onSubmit }
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderAddress () {
|
|
||||||
const { accounts, label, value, error } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<InputAddressSelect
|
|
||||||
accounts={ accounts }
|
|
||||||
label={ label }
|
|
||||||
value={ value }
|
|
||||||
error={ error }
|
|
||||||
onChange={ this.onChange }
|
|
||||||
editing
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderBoolean () {
|
|
||||||
const { label, value, error } = this.props;
|
|
||||||
|
|
||||||
const boolitems = ['false', 'true'].map((bool) => {
|
|
||||||
return (
|
|
||||||
<MenuItem
|
|
||||||
key={ bool }
|
|
||||||
value={ bool }
|
|
||||||
label={ bool }
|
|
||||||
>
|
|
||||||
{ bool }
|
|
||||||
</MenuItem>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
label={ label }
|
|
||||||
value={ value ? 'true' : 'false' }
|
|
||||||
error={ error }
|
|
||||||
onChange={ this.onChangeBool }
|
|
||||||
>
|
|
||||||
{ boolitems }
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
onChangeBool = (event, _index, value) => {
|
|
||||||
this.props.onChange(value === 'true');
|
|
||||||
}
|
|
||||||
|
|
||||||
onChange = (event, value) => {
|
|
||||||
this.props.onChange(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit = (value) => {
|
|
||||||
this.props.onChange(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
onAddField = () => {
|
|
||||||
const { value, onChange, param } = this.props;
|
|
||||||
const newValues = [].concat(value, param.subtype.default);
|
|
||||||
|
|
||||||
onChange(newValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
onRemoveField = () => {
|
|
||||||
const { value, onChange } = this.props;
|
|
||||||
const newValues = value.slice(0, -1);
|
|
||||||
|
|
||||||
onChange(newValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class DetailsStep extends Component {
|
export default class DetailsStep extends Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
api: PropTypes.object.isRequired
|
api: PropTypes.object.isRequired
|
||||||
@ -313,6 +103,7 @@ export default class DetailsStep extends Component {
|
|||||||
value={ code }
|
value={ code }
|
||||||
onSubmit={ this.onCodeChange }
|
onSubmit={ this.onCodeChange }
|
||||||
readOnly={ readOnly } />
|
readOnly={ readOnly } />
|
||||||
|
|
||||||
{ this.renderConstructorInputs() }
|
{ this.renderConstructorInputs() }
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
@ -400,125 +191,3 @@ export default class DetailsStep extends Component {
|
|||||||
onCodeChange(code);
|
onCodeChange(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ARRAY_TYPE = 'ARRAY_TYPE';
|
|
||||||
const ADDRESS_TYPE = 'ADDRESS_TYPE';
|
|
||||||
const STRING_TYPE = 'STRING_TYPE';
|
|
||||||
const BOOL_TYPE = 'BOOL_TYPE';
|
|
||||||
const BYTES_TYPE = 'BYTES_TYPE';
|
|
||||||
const INT_TYPE = 'INT_TYPE';
|
|
||||||
const FIXED_TYPE = 'FIXED_TYPE';
|
|
||||||
|
|
||||||
function parseAbiType (type) {
|
|
||||||
const arrayRegex = /^(.+)\[(\d*)\]$/;
|
|
||||||
|
|
||||||
if (arrayRegex.test(type)) {
|
|
||||||
const matches = arrayRegex.exec(type);
|
|
||||||
|
|
||||||
const subtype = parseAbiType(matches[1]);
|
|
||||||
const M = parseInt(matches[2]) || null;
|
|
||||||
const defaultValue = !M
|
|
||||||
? []
|
|
||||||
: range(M).map(() => subtype.default);
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: ARRAY_TYPE,
|
|
||||||
subtype: subtype,
|
|
||||||
length: M,
|
|
||||||
default: defaultValue
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const lengthRegex = /^(u?int|bytes)(\d{1,3})$/;
|
|
||||||
|
|
||||||
if (lengthRegex.test(type)) {
|
|
||||||
const matches = lengthRegex.exec(type);
|
|
||||||
|
|
||||||
const subtype = parseAbiType(matches[1]);
|
|
||||||
const length = parseInt(matches[2]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...subtype,
|
|
||||||
length
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const fixedLengthRegex = /^(u?fixed)(\d{1,3})x(\d{1,3})$/;
|
|
||||||
|
|
||||||
if (fixedLengthRegex.test(type)) {
|
|
||||||
const matches = fixedLengthRegex.exec(type);
|
|
||||||
|
|
||||||
const subtype = parseAbiType(matches[1]);
|
|
||||||
const M = parseInt(matches[2]);
|
|
||||||
const N = parseInt(matches[3]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...subtype,
|
|
||||||
M, N
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'string') {
|
|
||||||
return {
|
|
||||||
type: STRING_TYPE,
|
|
||||||
default: ''
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'bool') {
|
|
||||||
return {
|
|
||||||
type: BOOL_TYPE,
|
|
||||||
default: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'address') {
|
|
||||||
return {
|
|
||||||
type: ADDRESS_TYPE,
|
|
||||||
default: '0x'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'bytes') {
|
|
||||||
return {
|
|
||||||
type: BYTES_TYPE,
|
|
||||||
default: '0x'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'uint') {
|
|
||||||
return {
|
|
||||||
type: INT_TYPE,
|
|
||||||
default: 0,
|
|
||||||
length: 256,
|
|
||||||
signed: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'int') {
|
|
||||||
return {
|
|
||||||
type: INT_TYPE,
|
|
||||||
default: 0,
|
|
||||||
length: 256,
|
|
||||||
signed: true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'ufixed') {
|
|
||||||
return {
|
|
||||||
type: FIXED_TYPE,
|
|
||||||
default: 0,
|
|
||||||
length: 256,
|
|
||||||
signed: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'fixed') {
|
|
||||||
return {
|
|
||||||
type: FIXED_TYPE,
|
|
||||||
default: 0,
|
|
||||||
length: 256,
|
|
||||||
signed: true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -31,17 +31,3 @@
|
|||||||
.funcparams {
|
.funcparams {
|
||||||
padding-left: 3em;
|
padding-left: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inputs {
|
|
||||||
padding-top: 2px;
|
|
||||||
|
|
||||||
label {
|
|
||||||
line-height: 22px;
|
|
||||||
pointer-events: none;
|
|
||||||
color: rgba(255, 255, 255, 0.498039);
|
|
||||||
-webkit-user-select: none;
|
|
||||||
font-size: 12px;
|
|
||||||
top: 11px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -278,8 +278,6 @@ export default class DeployContract extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('onDeploymentState', data);
|
|
||||||
|
|
||||||
switch (data.state) {
|
switch (data.state) {
|
||||||
case 'estimateGas':
|
case 'estimateGas':
|
||||||
case 'postTransaction':
|
case 'postTransaction':
|
||||||
|
17
js/src/ui/Form/TypedInput/index.js
Normal file
17
js/src/ui/Form/TypedInput/index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
export default from './typedInput';
|
31
js/src/ui/Form/TypedInput/typedInput.css
Normal file
31
js/src/ui/Form/TypedInput/typedInput.css
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
/* This file is part of Parity.
|
||||||
|
/*
|
||||||
|
/* Parity is free software: you can redistribute it and/or modify
|
||||||
|
/* it under the terms of the GNU General Public License as published by
|
||||||
|
/* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
/* (at your option) any later version.
|
||||||
|
/*
|
||||||
|
/* Parity is distributed in the hope that it will be useful,
|
||||||
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
/* GNU General Public License for more details.
|
||||||
|
/*
|
||||||
|
/* You should have received a copy of the GNU General Public License
|
||||||
|
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.inputs {
|
||||||
|
padding-top: 2px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
label {
|
||||||
|
line-height: 22px;
|
||||||
|
pointer-events: none;
|
||||||
|
color: rgba(255, 255, 255, 0.498039);
|
||||||
|
-webkit-user-select: none;
|
||||||
|
font-size: 12px;
|
||||||
|
top: 11px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
239
js/src/ui/Form/TypedInput/typedInput.js
Normal file
239
js/src/ui/Form/TypedInput/typedInput.js
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import React, { Component, PropTypes } from 'react';
|
||||||
|
import { MenuItem } from 'material-ui';
|
||||||
|
import { range } from 'lodash';
|
||||||
|
|
||||||
|
import IconButton from 'material-ui/IconButton';
|
||||||
|
import AddIcon from 'material-ui/svg-icons/content/add';
|
||||||
|
import RemoveIcon from 'material-ui/svg-icons/content/remove';
|
||||||
|
|
||||||
|
import { Input, InputAddressSelect, Select } from '../../../ui';
|
||||||
|
import { ABI_TYPES } from '../../../util/abi';
|
||||||
|
|
||||||
|
import styles from './typedInput.css';
|
||||||
|
|
||||||
|
export default class TypedInput extends Component {
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
onChange: PropTypes.func.isRequired,
|
||||||
|
accounts: PropTypes.object.isRequired,
|
||||||
|
param: PropTypes.object.isRequired,
|
||||||
|
|
||||||
|
error: PropTypes.any,
|
||||||
|
value: PropTypes.any,
|
||||||
|
label: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { param } = this.props;
|
||||||
|
const { type } = param;
|
||||||
|
|
||||||
|
if (type === ABI_TYPES.ARRAY) {
|
||||||
|
const { accounts, label, value = param.default } = this.props;
|
||||||
|
const { subtype, length } = param;
|
||||||
|
|
||||||
|
const fixedLength = !!length;
|
||||||
|
|
||||||
|
const inputs = range(length || value.length).map((_, index) => {
|
||||||
|
const onChange = (inputValue) => {
|
||||||
|
const newValues = [].concat(this.props.value);
|
||||||
|
newValues[index] = inputValue;
|
||||||
|
this.props.onChange(newValues);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TypedInput
|
||||||
|
key={ `${subtype.type}_${index}` }
|
||||||
|
onChange={ onChange }
|
||||||
|
accounts={ accounts }
|
||||||
|
param={ subtype }
|
||||||
|
value={ value[index] }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ styles.inputs }>
|
||||||
|
<label>{ label }</label>
|
||||||
|
{ fixedLength ? null : this.renderLength() }
|
||||||
|
{ inputs }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.renderType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderLength () {
|
||||||
|
const iconStyle = {
|
||||||
|
width: 16,
|
||||||
|
height: 16
|
||||||
|
};
|
||||||
|
|
||||||
|
const style = {
|
||||||
|
width: 32,
|
||||||
|
height: 32,
|
||||||
|
padding: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<IconButton
|
||||||
|
iconStyle={ iconStyle }
|
||||||
|
style={ style }
|
||||||
|
onClick={ this.onAddField }
|
||||||
|
>
|
||||||
|
<AddIcon />
|
||||||
|
</IconButton>
|
||||||
|
|
||||||
|
<IconButton
|
||||||
|
iconStyle={ iconStyle }
|
||||||
|
style={ style }
|
||||||
|
onClick={ this.onRemoveField }
|
||||||
|
>
|
||||||
|
<RemoveIcon />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderType (type) {
|
||||||
|
if (type === ABI_TYPES.ADDRESS) {
|
||||||
|
return this.renderAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === ABI_TYPES.BOOL) {
|
||||||
|
return this.renderBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === ABI_TYPES.STRING) {
|
||||||
|
return this.renderDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === ABI_TYPES.BYTES) {
|
||||||
|
return this.renderDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === ABI_TYPES.INT) {
|
||||||
|
return this.renderNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === ABI_TYPES.FIXED) {
|
||||||
|
return this.renderNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.renderDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderNumber () {
|
||||||
|
const { label, value, error, param } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
label={ label }
|
||||||
|
value={ value }
|
||||||
|
error={ error }
|
||||||
|
onSubmit={ this.onSubmit }
|
||||||
|
type='number'
|
||||||
|
min={ param.signed ? null : 0 }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDefault () {
|
||||||
|
const { label, value, error } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Input
|
||||||
|
label={ label }
|
||||||
|
value={ value }
|
||||||
|
error={ error }
|
||||||
|
onSubmit={ this.onSubmit }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderAddress () {
|
||||||
|
const { accounts, label, value, error } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InputAddressSelect
|
||||||
|
accounts={ accounts }
|
||||||
|
label={ label }
|
||||||
|
value={ value }
|
||||||
|
error={ error }
|
||||||
|
onChange={ this.onChange }
|
||||||
|
editing
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderBoolean () {
|
||||||
|
const { label, value, error } = this.props;
|
||||||
|
|
||||||
|
const boolitems = ['false', 'true'].map((bool) => {
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
key={ bool }
|
||||||
|
value={ bool }
|
||||||
|
label={ bool }
|
||||||
|
>
|
||||||
|
{ bool }
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
label={ label }
|
||||||
|
value={ value ? 'true' : 'false' }
|
||||||
|
error={ error }
|
||||||
|
onChange={ this.onChangeBool }
|
||||||
|
>
|
||||||
|
{ boolitems }
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeBool = (event, _index, value) => {
|
||||||
|
this.props.onChange(value === 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange = (event, value) => {
|
||||||
|
this.props.onChange(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit = (value) => {
|
||||||
|
this.props.onChange(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddField = () => {
|
||||||
|
const { value, onChange, param } = this.props;
|
||||||
|
const newValues = [].concat(value, param.subtype.default);
|
||||||
|
|
||||||
|
onChange(newValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemoveField = () => {
|
||||||
|
const { value, onChange } = this.props;
|
||||||
|
const newValues = value.slice(0, -1);
|
||||||
|
|
||||||
|
onChange(newValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
import AddressSelect from './AddressSelect';
|
import AddressSelect from './AddressSelect';
|
||||||
import FormWrap from './FormWrap';
|
import FormWrap from './FormWrap';
|
||||||
|
import TypedInput from './TypedInput';
|
||||||
import Input from './Input';
|
import Input from './Input';
|
||||||
import InputAddress from './InputAddress';
|
import InputAddress from './InputAddress';
|
||||||
import InputAddressSelect from './InputAddressSelect';
|
import InputAddressSelect from './InputAddressSelect';
|
||||||
@ -27,6 +28,7 @@ export default from './form';
|
|||||||
export {
|
export {
|
||||||
AddressSelect,
|
AddressSelect,
|
||||||
FormWrap,
|
FormWrap,
|
||||||
|
TypedInput,
|
||||||
Input,
|
Input,
|
||||||
InputAddress,
|
InputAddress,
|
||||||
InputAddressSelect,
|
InputAddressSelect,
|
||||||
|
@ -29,7 +29,7 @@ import ContextProvider from './ContextProvider';
|
|||||||
import CopyToClipboard from './CopyToClipboard';
|
import CopyToClipboard from './CopyToClipboard';
|
||||||
import Editor from './Editor';
|
import Editor from './Editor';
|
||||||
import Errors from './Errors';
|
import Errors from './Errors';
|
||||||
import Form, { AddressSelect, FormWrap, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select } from './Form';
|
import Form, { AddressSelect, FormWrap, TypedInput, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select } from './Form';
|
||||||
import IdentityIcon from './IdentityIcon';
|
import IdentityIcon from './IdentityIcon';
|
||||||
import IdentityName from './IdentityName';
|
import IdentityName from './IdentityName';
|
||||||
import MethodDecoding from './MethodDecoding';
|
import MethodDecoding from './MethodDecoding';
|
||||||
@ -62,6 +62,7 @@ export {
|
|||||||
Errors,
|
Errors,
|
||||||
Form,
|
Form,
|
||||||
FormWrap,
|
FormWrap,
|
||||||
|
TypedInput,
|
||||||
Input,
|
Input,
|
||||||
InputAddress,
|
InputAddress,
|
||||||
InputAddressSelect,
|
InputAddressSelect,
|
||||||
|
146
js/src/util/abi.js
Normal file
146
js/src/util/abi.js
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import { range } from 'lodash';
|
||||||
|
|
||||||
|
const ARRAY_TYPE = 'ARRAY_TYPE';
|
||||||
|
const ADDRESS_TYPE = 'ADDRESS_TYPE';
|
||||||
|
const STRING_TYPE = 'STRING_TYPE';
|
||||||
|
const BOOL_TYPE = 'BOOL_TYPE';
|
||||||
|
const BYTES_TYPE = 'BYTES_TYPE';
|
||||||
|
const INT_TYPE = 'INT_TYPE';
|
||||||
|
const FIXED_TYPE = 'FIXED_TYPE';
|
||||||
|
|
||||||
|
export const ABI_TYPES = {
|
||||||
|
ARRAY: ARRAY_TYPE, ADDRESS: ADDRESS_TYPE,
|
||||||
|
STRING: STRING_TYPE, BOOL: BOOL_TYPE,
|
||||||
|
BYTES: BYTES_TYPE, INT: INT_TYPE,
|
||||||
|
FIXED: FIXED_TYPE
|
||||||
|
};
|
||||||
|
|
||||||
|
export function parseAbiType (type) {
|
||||||
|
const arrayRegex = /^(.+)\[(\d*)\]$/;
|
||||||
|
|
||||||
|
if (arrayRegex.test(type)) {
|
||||||
|
const matches = arrayRegex.exec(type);
|
||||||
|
|
||||||
|
const subtype = parseAbiType(matches[1]);
|
||||||
|
const M = parseInt(matches[2]) || null;
|
||||||
|
const defaultValue = !M
|
||||||
|
? []
|
||||||
|
: range(M).map(() => subtype.default);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: ARRAY_TYPE,
|
||||||
|
subtype: subtype,
|
||||||
|
length: M,
|
||||||
|
default: defaultValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const lengthRegex = /^(u?int|bytes)(\d{1,3})$/;
|
||||||
|
|
||||||
|
if (lengthRegex.test(type)) {
|
||||||
|
const matches = lengthRegex.exec(type);
|
||||||
|
|
||||||
|
const subtype = parseAbiType(matches[1]);
|
||||||
|
const length = parseInt(matches[2]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...subtype,
|
||||||
|
length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const fixedLengthRegex = /^(u?fixed)(\d{1,3})x(\d{1,3})$/;
|
||||||
|
|
||||||
|
if (fixedLengthRegex.test(type)) {
|
||||||
|
const matches = fixedLengthRegex.exec(type);
|
||||||
|
|
||||||
|
const subtype = parseAbiType(matches[1]);
|
||||||
|
const M = parseInt(matches[2]);
|
||||||
|
const N = parseInt(matches[3]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...subtype,
|
||||||
|
M, N
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'string') {
|
||||||
|
return {
|
||||||
|
type: STRING_TYPE,
|
||||||
|
default: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'bool') {
|
||||||
|
return {
|
||||||
|
type: BOOL_TYPE,
|
||||||
|
default: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'address') {
|
||||||
|
return {
|
||||||
|
type: ADDRESS_TYPE,
|
||||||
|
default: '0x'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'bytes') {
|
||||||
|
return {
|
||||||
|
type: BYTES_TYPE,
|
||||||
|
default: '0x'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'uint') {
|
||||||
|
return {
|
||||||
|
type: INT_TYPE,
|
||||||
|
default: 0,
|
||||||
|
length: 256,
|
||||||
|
signed: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'int') {
|
||||||
|
return {
|
||||||
|
type: INT_TYPE,
|
||||||
|
default: 0,
|
||||||
|
length: 256,
|
||||||
|
signed: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'ufixed') {
|
||||||
|
return {
|
||||||
|
type: FIXED_TYPE,
|
||||||
|
default: 0,
|
||||||
|
length: 256,
|
||||||
|
signed: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'fixed') {
|
||||||
|
return {
|
||||||
|
type: FIXED_TYPE,
|
||||||
|
default: 0,
|
||||||
|
length: 256,
|
||||||
|
signed: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user