diff --git a/README.md b/README.md index 560e475..548fe4a 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ import ReactJsonView from '@microlink/react-json-view' | `onAdd` | `(add)=>{}` | `false` | When a callback function is passed in, `add` functionality is enabled. The callback is invoked before additions are completed. Returning `false` from `onAdd` will prevent the change from being made. [see: onAdd docs](#onedit-onadd-and-ondelete-interaction) | | `defaultValue` | `string \| number \| boolean \| array \| object` | `null` | Sets the default value to be used when adding an item to JSON. | | `onDelete` | `(delete)=>{}` | `false` | When a callback function is passed in, `delete` functionality is enabled. The callback is invoked before deletions are completed. Returning `false` from `onDelete` will prevent the change from being made. [see: onDelete docs](#onedit-onadd-and-ondelete-interaction) | -| `onSelect` | `(select)=>{}` | `false` | When a function is passed in, clicking a value triggers the `onSelect` method to be called. | +| `onSelect` | `(select)=>{}` | `false` | When a function is passed in, clicking a value or a key triggers the `onSelect` method to be called. | | `sortKeys` | `boolean` | `false` | Set to `true` to sort object keys. | | `quotesOnKeys` | `boolean` | `true` | Set to `false` to remove quotes from keys (e.g., `"name":` vs. `name:`). | | `validationMessage` | `string` | "Validation Error" | Custom message for validation failures to `onEdit`, `onAdd`, or `onDelete` callbacks. | diff --git a/docs/src/js/components/Demo.js b/docs/src/js/components/Demo.js index 8fa9edd..7ef8307 100644 --- a/docs/src/js/components/Demo.js +++ b/docs/src/js/components/Demo.js @@ -4,7 +4,6 @@ import ReactJson from './../../../../src/js/index' import Code from './../helpers/Code' import './../../style/scss/rjv-demo.scss' -import 'react-select/dist/react-select.css' // index entrypoint component class Demo extends React.PureComponent { @@ -24,6 +23,7 @@ class Demo extends React.PureComponent { onAdd: true, onEdit: true, onDelete: true, + onSelect: true, displayObjectSize: true, enableClipboard: true, indentWidth: 4, @@ -88,7 +88,7 @@ class Demo extends React.PureComponent { componentDidMount () { this.updateStyles() - this.observer = new MutationObserver(this.updateStyles) + this.observer = new window.MutationObserver(this.updateStyles) this.observer.observe(document.querySelector('.react-json-view'), { attributes: true, childList: true, @@ -129,6 +129,7 @@ class Demo extends React.PureComponent { onAdd, onEdit, onDelete, + onSelect, displayObjectSize, enableClipboard, theme, @@ -157,21 +158,6 @@ class Demo extends React.PureComponent { .react-json-view { border: 1px solid ${this.state.siteTheme.borderColor}; } - - .Select-control, - .Select.is-open>.Select-control, - .Select-option, - .Select-option.is-selected, - .Select-option.is-focused { - background-color: ${this.state.siteTheme.bgColor}; - color: ${this.state.siteTheme.color}; - } - .Select-option.is-focused { - opacity: 0.8; - } - .Select.has-value.Select--single>.Select-control .Select-value .Select-value-label, .Select.has-value.is-pseudo-focused.Select--single>.Select-control .Select-value .Select-value-label { - color: ${this.state.siteTheme.color}; - } `} )} @@ -210,6 +196,13 @@ class Demo extends React.PureComponent { } : false } + onSelect={ + onSelect + ? e => { + console.log(e) + } + : false + } displayObjectSize={displayObjectSize} enableClipboard={enableClipboard} indentWidth={indentWidth} @@ -253,6 +246,10 @@ class Demo extends React.PureComponent {
Display Object Size:
{this.getObjectSizeInput(displayObjectSize)} +
+
Enable Select:
+ {this.getSelectInput(onSelect)} +
Indent Width:
{this.getIndentWidthInput(indentWidth)} @@ -273,9 +270,9 @@ class Demo extends React.PureComponent { ) } - getNotes = (on_edit_enabled, on_add_enabled) => { + getNotes = (onEditEnabled, onAddEnabled) => { const notes = [] - if (on_edit_enabled) { + if (onEditEnabled) { notes.push( To edit a value, try ctrl/cmd + click enter edit mode @@ -293,7 +290,7 @@ class Demo extends React.PureComponent { ) } - if (on_add_enabled) { + if (onAddEnabled) { notes.push( When adding a new key, try Enter to submit @@ -314,8 +311,8 @@ class Demo extends React.PureComponent {
Keyboard Shortcuts
    - {notes.map(note => { - return
  • {note}
  • + {notes.map((note, index) => { + return
  • {note}
  • })}
@@ -323,15 +320,17 @@ class Demo extends React.PureComponent { } getIconStyleInput = iconStyle => { + const options = [ + { value: 'circle', label: 'circle' }, + { value: 'square', label: 'square' }, + { value: 'triangle', label: 'triangle' } + ] return ( opt.value === iconStyle)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('iconStyle', val) }} @@ -340,14 +339,16 @@ class Demo extends React.PureComponent { } getEditInput = onEdit => { + const options = [ + { value: true, label: 'true' }, + { value: false, label: 'false' } + ] return ( opt.value === onEdit)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('onEdit', val) }} @@ -356,14 +357,16 @@ class Demo extends React.PureComponent { } getAddInput = onAdd => { + const options = [ + { value: true, label: 'true' }, + { value: false, label: 'false' } + ] return ( opt.value === onAdd)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('onAdd', val) }} @@ -372,14 +375,16 @@ class Demo extends React.PureComponent { } getDeleteInput = onDelete => { + const options = [ + { value: true, label: 'true' }, + { value: false, label: 'false' } + ] return ( opt.value === onDelete)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('onDelete', val) }} @@ -387,15 +392,35 @@ class Demo extends React.PureComponent { ) } + getSelectInput = onSelect => { + const options = [ + { value: true, label: 'true' }, + { value: false, label: 'false' } + ] + return ( + opt.value === onSelect)} + options={options} + styles={this.getSelectStyles()} + onChange={val => { + this.set('onSelect', val) + }} + /> + ) + } + getEnableClipboardInput = enableClipboard => { + const options = [ + { value: true, label: 'true' }, + { value: false, label: 'false' } + ] return ( opt.value === enableClipboard)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('enableClipboard', val) }} @@ -404,14 +429,16 @@ class Demo extends React.PureComponent { } getObjectSizeInput = displayObjectSize => { + const options = [ + { value: true, label: 'true' }, + { value: false, label: 'false' } + ] return ( opt.value === displayObjectSize)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('displayObjectSize', val) }} @@ -420,14 +447,16 @@ class Demo extends React.PureComponent { } getDataTypesInput = displayDataTypes => { + const options = [ + { value: true, label: 'true' }, + { value: false, label: 'false' } + ] return ( opt.value === displayDataTypes)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('displayDataTypes', val) }} @@ -436,17 +465,19 @@ class Demo extends React.PureComponent { } getCollapsedStringsInput = collapseStringsAfter => { + const options = [ + { value: false, label: 'false' }, + { value: 5, label: 5 }, + { value: 10, label: 10 }, + { value: 15, label: 15 }, + { value: 20, label: 20 } + ] return ( opt.value === collapseStringsAfter)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('collapseStringsAfter', val) }} @@ -455,16 +486,18 @@ class Demo extends React.PureComponent { } getCollapsedInput = collapsed => { + const options = [ + { value: true, label: 'true' }, + { value: false, label: 'false' }, + { value: 1, label: 1 }, + { value: 2, label: 2 } + ] return ( opt.value === collapsed)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('collapsed', val) }} @@ -473,23 +506,25 @@ class Demo extends React.PureComponent { } getIndentWidthInput = indentWidth => { + const options = [ + { value: 0, label: 0 }, + { value: 1, label: 1 }, + { value: 2, label: 2 }, + { value: 3, label: 3 }, + { value: 4, label: 4 }, + { value: 5, label: 5 }, + { value: 6, label: 6 }, + { value: 7, label: 7 }, + { value: 8, label: 8 }, + { value: 9, label: 9 }, + { value: 10, label: 10 } + ] return ( opt.value === indentWidth)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('indentWidth', val) }} @@ -498,58 +533,51 @@ class Demo extends React.PureComponent { } getThemeInput = theme => { + const options = [ + { value: 'apathy', label: 'apathy' }, + { value: 'apathy:inverted', label: 'apathy:inverted' }, + { value: 'ashes', label: 'ashes' }, + { value: 'bespin', label: 'bespin' }, + { value: 'brewer', label: 'brewer' }, + { value: 'bright:inverted', label: 'bright:inverted' }, + { value: 'bright', label: 'bright' }, + { value: 'chalk', label: 'chalk' }, + { value: 'codeschool', label: 'codeschool' }, + { value: 'colors', label: 'colors' }, + { value: 'eighties', label: 'eighties' }, + { value: 'embers', label: 'embers' }, + { value: 'flat', label: 'flat' }, + { value: 'google', label: 'google' }, + { value: 'grayscale', label: 'grayscale' }, + { value: 'grayscale:inverted', label: 'grayscale:inverted' }, + { value: 'greenscreen', label: 'greenscreen' }, + { value: 'harmonic', label: 'harmonic' }, + { value: 'hopscotch', label: 'hopscotch' }, + { value: 'isotope', label: 'isotope' }, + { value: 'marrakesh', label: 'marrakesh' }, + { value: 'mocha', label: 'mocha' }, + { value: 'monokai', label: 'monokai' }, + { value: 'ocean', label: 'ocean' }, + { value: 'paraiso', label: 'paraiso' }, + { value: 'pop', label: 'pop' }, + { value: 'railscasts', label: 'railscasts' }, + { value: 'rjv-default', label: 'rjv-default' }, + { value: 'shapeshifter', label: 'shapeshifter' }, + { value: 'shapeshifter:inverted', label: 'shapeshifter:inverted' }, + { value: 'solarized', label: 'solarized' }, + { value: 'summerfruit', label: 'summerfruit' }, + { value: 'summerfruit:inverted', label: 'summerfruit:inverted' }, + { value: 'threezerotwofour', label: 'threezerotwofour' }, + { value: 'tomorrow', label: 'tomorrow' }, + { value: 'tube', label: 'tube' }, + { value: 'twilight', label: 'twilight' } + ] return ( opt.value === theme)} + options={options} + styles={this.getSelectStyles()} onChange={val => { this.set('theme', val) }} @@ -557,6 +585,45 @@ class Demo extends React.PureComponent { ) } + getSelectStyles = () => { + const { siteTheme } = this.state + if (!siteTheme) return {} + return { + control: base => ({ + ...base, + backgroundColor: siteTheme.bgColor, + borderColor: siteTheme.borderColor, + color: siteTheme.color + }), + singleValue: base => ({ + ...base, + color: siteTheme.color + }), + option: (base, { isFocused }) => ({ + ...base, + backgroundColor: siteTheme.bgColor, + color: siteTheme.color, + opacity: isFocused ? 0.8 : 1 + }), + menu: base => ({ + ...base, + backgroundColor: siteTheme.bgColor + }), + input: base => ({ + ...base, + color: siteTheme.color + }), + indicatorSeparator: base => ({ + ...base, + backgroundColor: siteTheme.borderColor + }), + dropdownIndicator: base => ({ + ...base, + color: siteTheme.color + }) + } + } + set = (field, value) => { const state = {} state[field] = value.value diff --git a/docs/src/js/entry.js b/docs/src/js/entry.js index 59dd2e9..fe02c9d 100644 --- a/docs/src/js/entry.js +++ b/docs/src/js/entry.js @@ -5,7 +5,7 @@ require('./../style/scss/global.scss') const app = document.getElementById('mac-react-container') -//app entrypoint +// app entrypoint ReactDom.render(
diff --git a/index.d.ts b/index.d.ts index 3d49b19..e3ce1a5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -124,7 +124,7 @@ export interface ReactJsonViewProps { */ onDelete?: ((del: InteractionProps) => false | any) | false /** - * When a function is passed in, clicking a value triggers the onSelect method to be called. + * When a function is passed in, clicking a value or a key triggers the onSelect method to be called. * * Default: false */ diff --git a/package.json b/package.json index d58977a..77b6d24 100644 --- a/package.json +++ b/package.json @@ -248,7 +248,7 @@ "prettier": "~2.2.1", "react": "~16.14.0", "react-dom": "~16.14.0", - "react-select": "~1.1.0", + "react-select": "~5.10.2", "react-test-renderer": "~16.14.0", "sass": "~1.47.0", "sass-loader": "~10.1.1", diff --git a/src/js/components/ArrayGroup.js b/src/js/components/ArrayGroup.js index 35b8215..c834fd1 100644 --- a/src/js/components/ArrayGroup.js +++ b/src/js/components/ArrayGroup.js @@ -42,6 +42,27 @@ export default class extends React.PureComponent { return } + handleKeySelect = () => { + const { name, namespace, onSelect, src } = this.props + + if (typeof onSelect !== 'function') { + return + } + + const location = [...namespace] + location.shift() + if (location.length > 0) { + location.pop() + } + + onSelect({ + name, + value: src, + type: 'array', + namespace: location + }) + } + render () { const { src, @@ -51,16 +72,15 @@ export default class extends React.PureComponent { theme, jsvRoot, namespace, - parent_type, ...rest } = this.props - let object_padding_left = 0 + let objectPaddingLeft = 0 - const array_group_padding_left = this.props.indentWidth * SINGLE_INDENT + const arrayGroupPaddingLeft = this.props.indentWidth * SINGLE_INDENT if (!jsvRoot) { - object_padding_left = this.props.indentWidth * SINGLE_INDENT + objectPaddingLeft = this.props.indentWidth * SINGLE_INDENT } const size = groupArraysAfterLength @@ -70,10 +90,10 @@ export default class extends React.PureComponent {
- + @@ -84,7 +104,7 @@ export default class extends React.PureComponent { className='object-key-val array-group' {...Theme(theme, 'objectKeyVal', { marginLeft: 6, - paddingLeft: array_group_padding_left + paddingLeft: arrayGroupPaddingLeft })} > @@ -129,7 +149,10 @@ export default class extends React.PureComponent { {...Theme(theme, 'array-group-meta-data')} className='array-group-meta-data' > - + {i * size} {' - '} {i * size + size > src.length diff --git a/src/js/components/CopyToClipboard.js b/src/js/components/CopyToClipboard.js index 1da352c..2608e38 100644 --- a/src/js/components/CopyToClipboard.js +++ b/src/js/components/CopyToClipboard.js @@ -95,7 +95,7 @@ export default class extends React.PureComponent { } render () { - const { src, theme, hidden, rowHovered } = this.props + const { theme, hidden, rowHovered } = this.props const style = Theme(theme, 'copy-to-clipboard').style let display = 'inline' diff --git a/src/js/components/DataTypes/BigNumber.js b/src/js/components/DataTypes/BigNumber.js index 289e168..ccb9e60 100644 --- a/src/js/components/DataTypes/BigNumber.js +++ b/src/js/components/DataTypes/BigNumber.js @@ -6,11 +6,11 @@ import Theme from './../../themes/getStyle' export default class extends React.PureComponent { render () { - const type_name = 'bigNumber' + const typeName = 'bigNumber' const { props } = this return (
- + {this.props.value.toString()}
) diff --git a/src/js/components/DataTypes/Boolean.js b/src/js/components/DataTypes/Boolean.js index ab7d4ca..acfae92 100644 --- a/src/js/components/DataTypes/Boolean.js +++ b/src/js/components/DataTypes/Boolean.js @@ -6,12 +6,12 @@ import Theme from './../../themes/getStyle' export default class extends React.PureComponent { render () { - const type_name = 'bool' + const typeName = 'bool' const { props } = this return (
- + {props.value ? 'true' : 'false'}
) diff --git a/src/js/components/DataTypes/DataTypeLabel.js b/src/js/components/DataTypes/DataTypeLabel.js index e8ee9da..d43b7c4 100644 --- a/src/js/components/DataTypes/DataTypeLabel.js +++ b/src/js/components/DataTypes/DataTypeLabel.js @@ -5,11 +5,11 @@ import Theme from './../../themes/getStyle' export default class extends React.PureComponent { render () { - const { rjvId, type_name, displayDataTypes, theme } = this.props + const { typeName, displayDataTypes, theme } = this.props if (displayDataTypes) { return ( - {type_name} + {typeName} ) } diff --git a/src/js/components/DataTypes/Date.js b/src/js/components/DataTypes/Date.js index 518bcc8..a58ec4d 100644 --- a/src/js/components/DataTypes/Date.js +++ b/src/js/components/DataTypes/Date.js @@ -6,9 +6,9 @@ import Theme from './../../themes/getStyle' export default class extends React.PureComponent { render () { - const type_name = 'date' + const typeName = 'date' const { props } = this - const display_options = { + const displayOptions = { weekday: 'short', year: 'numeric', month: 'short', @@ -18,9 +18,9 @@ export default class extends React.PureComponent { } return (
- + - {props.value.toLocaleTimeString('en-us', display_options)} + {props.value.toLocaleTimeString('en-us', displayOptions)}
) diff --git a/src/js/components/DataTypes/Float.js b/src/js/components/DataTypes/Float.js index 0105817..6418b10 100644 --- a/src/js/components/DataTypes/Float.js +++ b/src/js/components/DataTypes/Float.js @@ -6,11 +6,11 @@ import Theme from './../../themes/getStyle' export default class extends React.PureComponent { render () { - const type_name = 'float' + const typeName = 'float' const { props } = this return (
- + {this.props.value}
) diff --git a/src/js/components/DataTypes/Function.js b/src/js/components/DataTypes/Function.js index 2e6c254..cefb982 100644 --- a/src/js/components/DataTypes/Function.js +++ b/src/js/components/DataTypes/Function.js @@ -20,7 +20,7 @@ export default class extends React.PureComponent { } } - toggleCollapsed = () => { + handleToggleCollapsed = () => { this.setState( { collapsed: !this.state.collapsed @@ -38,17 +38,17 @@ export default class extends React.PureComponent { } render () { - const type_name = 'function' + const typeName = 'function' const { props } = this const { collapsed } = this.state return (
- + {this.getFunctionDisplay(collapsed)} diff --git a/src/js/components/DataTypes/Integer.js b/src/js/components/DataTypes/Integer.js index 86d04d4..97ffecf 100644 --- a/src/js/components/DataTypes/Integer.js +++ b/src/js/components/DataTypes/Integer.js @@ -6,11 +6,11 @@ import Theme from './../../themes/getStyle' export default class extends React.PureComponent { render () { - const type_name = 'int' + const typeName = 'int' const { props } = this return (
- + {this.props.value}
) diff --git a/src/js/components/DataTypes/Object.js b/src/js/components/DataTypes/Object.js index 0334d4e..05edfc8 100644 --- a/src/js/components/DataTypes/Object.js +++ b/src/js/components/DataTypes/Object.js @@ -81,7 +81,7 @@ class RjvObject extends React.PureComponent { return null } - toggleCollapsed = () => { + handleToggleCollapsed = () => { this.setState( { expanded: !this.state.expanded @@ -97,6 +97,28 @@ class RjvObject extends React.PureComponent { ) } + handleKeySelect = () => { + const { name, namespace, onSelect, src } = this.props + const { object_type: objectType } = this.state + + if (typeof onSelect !== 'function') { + return + } + + const location = [...namespace] + location.shift() + if (location.length > 0) { + location.pop() + } + + onSelect({ + name, + value: src, + type: objectType, + namespace: location + }) + } + getObjectContent = (depth, src, props) => { return (
@@ -121,7 +143,7 @@ class RjvObject extends React.PureComponent {
...
@@ -130,19 +152,18 @@ class RjvObject extends React.PureComponent { } getObjectMetaData = src => { - const { rjvId, theme } = this.props const { size, hovered } = this.state return } - getBraceStart (object_type, expanded) { - const { src, theme, iconStyle, parent_type } = this.props + getBraceStart (objectType, expanded) { + const { theme, iconStyle, parent_type: parentType } = this.props - if (parent_type === 'array_group') { + if (parentType === 'array_group') { return ( - {object_type === 'array' ? '[' : '{'} + {objectType === 'array' ? '[' : '{'} ) @@ -153,17 +174,15 @@ class RjvObject extends React.PureComponent { return ( { - this.toggleCollapsed() - }} + onClick={this.handleToggleCollapsed} {...Theme(theme, 'brace-row')} >
- + - {object_type === 'array' ? '[' : '{'} + {objectType === 'array' ? '[' : '{'}
@@ -179,7 +198,7 @@ class RjvObject extends React.PureComponent { namespace, name, type, - parent_type, + parent_type: parentType, theme, jsvRoot, iconStyle, @@ -188,12 +207,12 @@ class RjvObject extends React.PureComponent { ...rest } = this.props - const { object_type, expanded } = this.state + const { object_type: objectType, expanded } = this.state const styles = {} - if (!jsvRoot && parent_type !== 'array_group') { + if (!jsvRoot && parentType !== 'array_group') { styles.paddingLeft = this.props.indentWidth * SINGLE_INDENT - } else if (parent_type === 'array_group') { + } else if (parentType === 'array_group') { styles.borderLeft = 0 styles.display = 'inline' } @@ -205,7 +224,7 @@ class RjvObject extends React.PureComponent { onMouseLeave={() => this.setState({ ...this.state, hovered: false })} {...Theme(theme, jsvRoot ? 'jsv-root' : 'objectKeyVal', styles)} > - {this.getBraceStart(object_type, expanded)} + {this.getBraceStart(objectType, expanded)} {expanded ? this.getObjectContent(depth, src, { theme, @@ -220,13 +239,11 @@ class RjvObject extends React.PureComponent { paddingLeft: expanded ? '3px' : '0px' }} > - {object_type === 'array' ? ']' : '}'} + {objectType === 'array' ? ']' : '}'} {showComma && !isLast && !jsvRoot && ( - - , - + , )} {this.getObjectMetaData(src)}
@@ -236,17 +253,17 @@ class RjvObject extends React.PureComponent { renderObjectContents = (variables, props) => { const { depth, - parent_type, - index_offset, + parent_type: parentType, + index_offset: indexOffset, groupArraysAfterLength, namespace, - showComma, + showComma } = this.props - const { object_type } = this.state + const { object_type: objectType } = this.state const elements = [] let variable let keys = Object.keys(variables || {}) - if (this.props.sortKeys && object_type !== 'array') { + if (this.props.sortKeys && objectType !== 'array') { keys = keys.sort() } @@ -254,11 +271,13 @@ class RjvObject extends React.PureComponent { variable = new JsonVariable(name, variables[name], props.bigNumber) const isLast = index === keys.length - 1 - if (parent_type === 'array_group' && index_offset) { - variable.name = parseInt(variable.name) + index_offset + if (parentType === 'array_group' && indexOffset) { + variable.name = parseInt(variable.name, 10) + indexOffset } if (!Object.prototype.hasOwnProperty.call(variables, name)) { - } else if (variable.type === 'object') { + return + } + if (variable.type === 'object') { elements.push( - + {this.props.value.toString()}
) diff --git a/src/js/components/DataTypes/String.js b/src/js/components/DataTypes/String.js index e23a785..0b39be3 100644 --- a/src/js/components/DataTypes/String.js +++ b/src/js/components/DataTypes/String.js @@ -21,7 +21,7 @@ export default class extends React.PureComponent { } } - toggleCollapsed = () => { + handleToggleCollapsed = () => { this.setState( { collapsed: !this.state.collapsed @@ -38,7 +38,7 @@ export default class extends React.PureComponent { } render () { - const type_name = 'string' + const typeName = 'string' const { collapsed } = this.state const { props } = this const { collapseStringsAfterLength, theme, escapeStrings } = props @@ -64,8 +64,12 @@ export default class extends React.PureComponent { return (
- - + + "{value}"
diff --git a/src/js/components/ObjectKeyModal/AddKeyRequest.js b/src/js/components/ObjectKeyModal/AddKeyRequest.js index 62933b0..0c18ba3 100644 --- a/src/js/components/ObjectKeyModal/AddKeyRequest.js +++ b/src/js/components/ObjectKeyModal/AddKeyRequest.js @@ -3,9 +3,6 @@ import dispatcher from './../../helpers/dispatcher' import ObjectAttributes from './../../stores/ObjectAttributes' import ObjectKeyModal from './ObjectKeyModal' -// global theme -import Theme from './../../themes/getStyle' - // this input appears when adding a new value to an object export default class extends React.PureComponent { render () { @@ -27,7 +24,7 @@ export default class extends React.PureComponent { const { rjvId } = this.props const request = ObjectAttributes.get(rjvId, 'action', 'new-key-request') return ( - input != '' && Object.keys(request.existing_value).indexOf(input) === -1 + input !== '' && Object.keys(request.existing_value).indexOf(input) === -1 ) } diff --git a/src/js/components/ObjectKeyModal/ObjectKeyModal.js b/src/js/components/ObjectKeyModal/ObjectKeyModal.js index 0856e2a..2841e2e 100644 --- a/src/js/components/ObjectKeyModal/ObjectKeyModal.js +++ b/src/js/components/ObjectKeyModal/ObjectKeyModal.js @@ -25,7 +25,7 @@ export default class extends React.PureComponent {
{ if (valid && e.key === 'Enter') { - this.submit() + this.handleSubmit() } else if (e.key === 'Escape') { - this.closeModal() + this.handleCloseModal() } }} /> @@ -60,7 +60,7 @@ export default class extends React.PureComponent { this.submit()} + onClick={this.handleSubmit} /> ) : null} @@ -82,14 +82,14 @@ export default class extends React.PureComponent { ) } - closeModal = () => { + handleCloseModal = () => { dispatcher.dispatch({ rjvId: this.props.rjvId, name: 'RESET' }) } - submit = () => { + handleSubmit = () => { this.props.submit(this.state.input) } } diff --git a/src/js/components/ObjectName.js b/src/js/components/ObjectName.js index 576b4bb..535ec98 100644 --- a/src/js/components/ObjectName.js +++ b/src/js/components/ObjectName.js @@ -3,24 +3,30 @@ import Theme from './../themes/getStyle' export default function getObjectName (props) { const { - parent_type, + parent_type: parentType, namespace, quotesOnKeys, theme, jsvRoot, name, - displayArrayKey + displayArrayKey, + onKeyClick } = props - const display_name = props.name ? props.name : '' + const displayName = props.name ? props.name : '' + const clickHandler = typeof onKeyClick === 'function' ? onKeyClick : null if (jsvRoot && (name === false || name === null)) { return - } else if (parent_type == 'array') { + } else if (parentType === 'array') { return displayArrayKey ? ( - - {display_name} + + {displayName} : ) @@ -29,10 +35,14 @@ export default function getObjectName (props) { ) } else { return ( - + {quotesOnKeys && "} - {display_name} + {displayName} {quotesOnKeys && "} : diff --git a/src/js/components/ValidationFailure.js b/src/js/components/ValidationFailure.js index a707a66..0b0b153 100644 --- a/src/js/components/ValidationFailure.js +++ b/src/js/components/ValidationFailure.js @@ -1,6 +1,5 @@ import React from 'react' import dispatcher from './../helpers/dispatcher' -import ObjectAttributes from './../stores/ObjectAttributes' import { Add as Clear } from './icons' diff --git a/src/js/components/VariableEditor.js b/src/js/components/VariableEditor.js index 2d14b10..c88b3d4 100644 --- a/src/js/components/VariableEditor.js +++ b/src/js/components/VariableEditor.js @@ -57,11 +57,11 @@ class VariableEditor extends React.PureComponent { onSelect, displayArrayKey, quotesOnKeys, - keyModifier, showComma, isLast } = this.props const { editMode } = this.state + const clickEnabled = onSelect !== false || onEdit !== false return (
- {type == 'array' + {type === 'array' ? ( displayArrayKey ? ( @@ -92,11 +92,14 @@ class VariableEditor extends React.PureComponent { {...Theme(theme, 'object-name')} className='object-key' key={variable.name + '_' + namespace} + onClick={clickEnabled ? this.handleSelect : null} > {!!quotesOnKeys && ( " )} - {escapeString(variable.name)} + + {escapeString(variable.name)} + {!!quotesOnKeys && ( " )} @@ -106,33 +109,14 @@ class VariableEditor extends React.PureComponent { )}
{ - const location = [...namespace] - if (keyModifier(e, 'edit') && onEdit !== false) { - this.prepopInput(variable) - } else if (onSelect !== false) { - location.shift() - onSelect({ - ...variable, - namespace: location - }) - } - } - } + onClick={clickEnabled ? this.handleSelect : null} {...Theme(theme, 'variableValue', { cursor: onSelect === false ? 'default' : 'pointer' })} > {this.getValue(variable, editMode)}
- {showComma && !isLast && ( - - , - - )} + {showComma && !isLast && ,} {enableClipboard ? ( ) : null} - {onEdit !== false && editMode == false ? this.getEditIcon() : null} - {onDelete !== false && editMode == false ? this.getRemoveIcon() : null} + {onEdit !== false && editMode === false ? this.getEditIcon() : null} + {onDelete !== false && editMode === false ? this.getRemoveIcon() : null}
) } + handleSelect = e => { + const { variable, namespace, onEdit, onSelect, keyModifier } = this.props + + const location = [...namespace] + if (keyModifier(e, 'edit') && onEdit !== false) { + this.prepopInput(variable) + } else if (onSelect !== false) { + location.shift() + onSelect({ + ...variable, + namespace: location + }) + } + } + getEditIcon = () => { const { variable, theme } = this.props @@ -174,7 +173,10 @@ class VariableEditor extends React.PureComponent { prepopInput = variable => { if (this.props.onEdit !== false) { - const stringifiedValue = stringifyVariable(variable.value, this.props.bigNumber) + const stringifiedValue = stringifyVariable( + variable.value, + this.props.bigNumber + ) const detected = parseInput(stringifiedValue, this.props.bigNumber) this.setState({ editMode: true, @@ -248,7 +250,9 @@ class VariableEditor extends React.PureComponent { return default: // catch-all for types that weren't anticipated - return
{JSON.stringify(variable.value)}
+ return ( +
{JSON.stringify(variable.value)}
+ ) } } @@ -329,16 +333,16 @@ class VariableEditor extends React.PureComponent { ) } - submitEdit = submit_detected => { + submitEdit = submitDetected => { const { variable, namespace, rjvId, bigNumber: BigNumber } = this.props const { editValue, parsedInput } = this.state - let new_value = editValue - if (submit_detected && parsedInput.type) { - new_value = parsedInput.value + let newValue = editValue + if (submitDetected && parsedInput.type) { + newValue = parsedInput.value if (BigNumber && parsedInput.type === 'bigNumber') { - new_value = new BigNumber(new_value) + newValue = new BigNumber(newValue) } - } + } this.setState({ editMode: false }) @@ -349,15 +353,14 @@ class VariableEditor extends React.PureComponent { name: variable.name, namespace, existing_value: variable.value, - new_value, + new_value: newValue, variable_removed: false } }) } showDetected = () => { - const { theme, variable, namespace, rjvId } = this.props - const { type, value } = this.state.parsedInput + const { theme } = this.props const detected = this.getDetectedInput() if (detected) { return ( diff --git a/src/js/components/VariableMeta.js b/src/js/components/VariableMeta.js index 1da8d9d..143d082 100644 --- a/src/js/components/VariableMeta.js +++ b/src/js/components/VariableMeta.js @@ -67,7 +67,7 @@ export default class extends React.PureComponent { } getRemoveObject = rowHovered => { - const { theme, hover, namespace, name, src, rjvId } = this.props + const { theme, namespace, name, src, rjvId } = this.props // don't allow deleting of root node if (namespace.length === 1) { diff --git a/src/js/components/icons.js b/src/js/components/icons.js index 0f5e41f..06bbde9 100644 --- a/src/js/components/icons.js +++ b/src/js/components/icons.js @@ -1,7 +1,5 @@ import React from 'react' -const DEFAULT_WIDTH = 24 -const DEFAULT_HEIGHT = 24 const DEFAULT_COLOR = '#000000' export class CircleMinus extends React.PureComponent { diff --git a/src/js/helpers/dispatcher.js b/src/js/helpers/dispatcher.js index 364a74a..a6e1222 100644 --- a/src/js/helpers/dispatcher.js +++ b/src/js/helpers/dispatcher.js @@ -1,11 +1,11 @@ class Dispatcher { handler = () => {} - register(handler) { + register (handler) { this.handler = handler } - dispatch(data) { + dispatch (data) { this.handler?.(data) } } diff --git a/src/js/helpers/parseInput.js b/src/js/helpers/parseInput.js index 39aaca5..825abb2 100644 --- a/src/js/helpers/parseInput.js +++ b/src/js/helpers/parseInput.js @@ -13,8 +13,8 @@ export default function parseInput (input, bigNumber) { // object return formatResponse('object', JSON.parse(input)) } else if ( - input.match(/\-?\d+\.\d+/) && - input.match(/\-?\d+\.\d+/)[0] === input + input.match(/-?\d+\.\d+/) && + input.match(/-?\d+\.\d+/)[0] === input ) { // big number if (bigNumber && parseFloat(input).toString() !== input) { @@ -23,12 +23,12 @@ export default function parseInput (input, bigNumber) { // float return formatResponse('float', parseFloat(input)) } else if ( - input.match(/\-?\d+e-\d+/) && - input.match(/\-?\d+e-\d+/)[0] === input + input.match(/-?\d+e-\d+/) && + input.match(/-?\d+e-\d+/)[0] === input ) { // scientific float return formatResponse('float', Number(input)) - } else if (input.match(/\-?\d+/) && input.match(/\-?\d+/)[0] === input) { + } else if (input.match(/-?\d+/) && input.match(/-?\d+/)[0] === input) { // big number if (bigNumber && parseInt(input).toString() !== input) { return formatResponse('bigNumber', input) @@ -36,8 +36,8 @@ export default function parseInput (input, bigNumber) { // integer return formatResponse('integer', parseInt(input)) } else if ( - input.match(/\-?\d+e\+\d+/) && - input.match(/\-?\d+e\+\d+/)[0] === input + input.match(/-?\d+e\+\d+/) && + input.match(/-?\d+e\+\d+/)[0] === input ) { // scientific integer return formatResponse('integer', Number(input)) diff --git a/src/js/helpers/stringifyVariable.js b/src/js/helpers/stringifyVariable.js index ad4275b..f605040 100644 --- a/src/js/helpers/stringifyVariable.js +++ b/src/js/helpers/stringifyVariable.js @@ -2,38 +2,38 @@ import { toType } from './util' export default (value, bigNumber) => { const type = toType(value, bigNumber) - let string_value + let stringValue switch (type) { case 'undefined': { - string_value = 'undefined' + stringValue = 'undefined' break } case 'nan': - string_value = 'NaN' + stringValue = 'NaN' break case 'string': - string_value = value + stringValue = value break case 'bigNumber': - string_value = value.toString() + stringValue = value.toString() break case 'date': - string_value = value.toString() + stringValue = value.toString() break case 'function': - string_value = value.toString() + stringValue = value.toString() break case 'regexp': - string_value = value.toString() + stringValue = value.toString() break default: { try { - string_value = JSON.stringify(value, null, ' ') + stringValue = JSON.stringify(value, null, ' ') } catch (e) { - string_value = '' + stringValue = '' } } } - return string_value + return stringValue } diff --git a/src/js/helpers/util.js b/src/js/helpers/util.js index 04e332b..91eaa70 100644 --- a/src/js/helpers/util.js +++ b/src/js/helpers/util.js @@ -1,6 +1,5 @@ // returns a string "type" of input object export function toType (obj, bigNumber) { - /* Check if the object is an instance of the custom BigNumber class passed in as a prop * If it matches, return 'bigNumber' type so it can be displayed appropriately */ @@ -12,7 +11,7 @@ export function toType (obj, bigNumber) { if (type === 'number') { if (isNaN(obj)) { type = 'nan' - } else if ((obj | 0) != obj) { + } else if ((obj | 0) !== obj) { // bitwise OR produces integers type = 'float' } else { @@ -41,7 +40,7 @@ export function escapeString (value) { // validation for base-16 themes export function isTheme (theme) { - const theme_keys = [ + const themeKeys = [ 'base00', 'base01', 'base02', @@ -60,8 +59,8 @@ export function isTheme (theme) { 'base0F' ] if (toType(theme) === 'object') { - for (let i = 0; i < theme_keys.length; i++) { - if (!(theme_keys[i] in theme)) { + for (let i = 0; i < themeKeys.length; i++) { + if (!(themeKeys[i] in theme)) { return false } } diff --git a/src/js/stores/ObjectAttributes.js b/src/js/stores/ObjectAttributes.js index 303d38b..ff53820 100644 --- a/src/js/stores/ObjectAttributes.js +++ b/src/js/stores/ObjectAttributes.js @@ -2,6 +2,10 @@ import { EventEmitter } from 'events' import dispatcher from './../helpers/dispatcher' import { toType } from './../helpers/util' +const UPDATED_SRC_KEY = 'updated_src' +const NEW_VALUE_KEY = 'new_value' +const VARIABLE_REMOVED_KEY = 'variable_removed' + // store persistent display attributes for objects and arrays class ObjectAttributes extends EventEmitter { objects = {} @@ -16,13 +20,13 @@ class ObjectAttributes extends EventEmitter { this.objects[rjvId][name][key] = value } - get = (rjvId, name, key, default_value) => { + get = (rjvId, name, key, defaultValue) => { if ( this.objects[rjvId] === undefined || this.objects[rjvId][name] === undefined || - this.objects[rjvId][name][key] == undefined + this.objects[rjvId][name][key] === undefined ) { - return default_value + return defaultValue } return this.objects[rjvId][name][key] } @@ -34,7 +38,7 @@ class ObjectAttributes extends EventEmitter { this.emit('reset-' + rjvId) break case 'VARIABLE_UPDATED': - action.data.updated_src = this.updateSrc(rjvId, data) + action.data[UPDATED_SRC_KEY] = this.updateSrc(rjvId, data) this.set(rjvId, 'action', 'variable-update', { ...data, type: 'variable-edited' @@ -42,7 +46,7 @@ class ObjectAttributes extends EventEmitter { this.emit('variable-update-' + rjvId) break case 'VARIABLE_REMOVED': - action.data.updated_src = this.updateSrc(rjvId, data) + action.data[UPDATED_SRC_KEY] = this.updateSrc(rjvId, data) this.set(rjvId, 'action', 'variable-update', { ...data, type: 'variable-removed' @@ -50,7 +54,7 @@ class ObjectAttributes extends EventEmitter { this.emit('variable-update-' + rjvId) break case 'VARIABLE_ADDED': - action.data.updated_src = this.updateSrc(rjvId, data) + action.data[UPDATED_SRC_KEY] = this.updateSrc(rjvId, data) this.set(rjvId, 'action', 'variable-update', { ...data, type: 'variable-added' @@ -65,24 +69,25 @@ class ObjectAttributes extends EventEmitter { } updateSrc = (rjvId, request) => { - const { name, namespace, new_value, existing_value, variable_removed } = - request + const { name, namespace } = request + const newValue = request[NEW_VALUE_KEY] + const variableRemoved = request[VARIABLE_REMOVED_KEY] namespace.shift() // deepy copy src const src = this.get(rjvId, 'global', 'src') // deep copy of src variable - let updated_src = this.deepCopy(src, [...namespace]) + let updatedSrc = this.deepCopy(src, [...namespace]) // point at current index - let walk = updated_src + let walk = updatedSrc for (const idx of namespace) { walk = walk[idx] } - if (variable_removed) { - if (toType(walk) == 'array') { + if (variableRemoved) { + if (toType(walk) === 'array') { walk.splice(name, 1) } else { delete walk[name] @@ -90,28 +95,28 @@ class ObjectAttributes extends EventEmitter { } else { // update copied variable at specified namespace if (name !== null) { - walk[name] = new_value + walk[name] = newValue } else { - updated_src = new_value + updatedSrc = newValue } } - this.set(rjvId, 'global', 'src', updated_src) + this.set(rjvId, 'global', 'src', updatedSrc) - return updated_src + return updatedSrc } - deepCopy = (src, copy_namespace) => { + deepCopy = (src, copyNamespace) => { const type = toType(src) let result - const idx = copy_namespace.shift() - if (type == 'array') { + const idx = copyNamespace.shift() + if (type === 'array') { result = [...src] - } else if (type == 'object') { + } else if (type === 'object') { result = { ...src } } if (idx !== undefined) { - result[idx] = this.deepCopy(src[idx], copy_namespace) + result[idx] = this.deepCopy(src[idx], copyNamespace) } return result } diff --git a/src/js/themes/base16/rjv-themes.js b/src/js/themes/base16/rjv-themes.js index 8dac891..ddd90b7 100644 --- a/src/js/themes/base16/rjv-themes.js +++ b/src/js/themes/base16/rjv-themes.js @@ -1,4 +1,4 @@ -export const rjv_default = { +export const rjvDefault = { scheme: 'rjv-default', author: 'mac gainor', // transparent main background @@ -20,7 +20,7 @@ export const rjv_default = { base0F: '#268bd2' } -export const rjv_grey = { +export const rjvGrey = { scheme: 'rjv-grey', author: 'mac gainor', base00: 'rgba(1, 1, 1, 0)', diff --git a/src/js/themes/getStyle.js b/src/js/themes/getStyle.js index dff05f0..306865d 100644 --- a/src/js/themes/getStyle.js +++ b/src/js/themes/getStyle.js @@ -1,4 +1,4 @@ -import { rjv_default, rjv_grey } from './base16/rjv-themes' +import { rjvDefault, rjvGrey } from './base16/rjv-themes' import constants from './styleConstants' import { createStyling } from 'react-base16-styling' @@ -90,7 +90,7 @@ const getDefaultThemeStyling = theme => { color: colors.keyColor, verticalAlign: 'top' }, - objectKeyVal: (component, variable_style) => { + objectKeyVal: (component, variableStyle) => { return { style: { paddingTop: constants.keyValPaddingTop, @@ -98,10 +98,10 @@ const getDefaultThemeStyling = theme => { paddingBottom: constants.keyValPaddingBottom, borderLeft: constants.keyValBorderLeft + ' ' + colors.objectBorder, ':hover': { - paddingLeft: variable_style.paddingLeft - 1 + 'px', + paddingLeft: variableStyle.paddingLeft - 1 + 'px', borderLeft: constants.keyValBorderHover + ' ' + colors.objectBorder }, - ...variable_style + ...variableStyle } } }, @@ -111,13 +111,13 @@ const getDefaultThemeStyling = theme => { 'pushed-content': { marginLeft: constants.pushedContentMarginLeft }, - variableValue: (component, variable_style) => { + variableValue: (component, variableStyle) => { return { style: { display: 'inline-block', paddingRight: constants.variableValuePaddingRight, position: 'relative', - ...variable_style + ...variableStyle } } }, @@ -398,12 +398,12 @@ const getDefaultThemeStyling = theme => { } const getStyle = theme => { - let rjv_theme = rjv_default + let rjvTheme = rjvDefault if (theme === false || theme === 'none') { - rjv_theme = rjv_grey + rjvTheme = rjvGrey } - return createStyling(getDefaultThemeStyling, { defaultBase16: rjv_theme })( + return createStyling(getDefaultThemeStyling, { defaultBase16: rjvTheme })( theme ) } diff --git a/src/js/themes/styleConstants.js b/src/js/themes/styleConstants.js index 4b921a6..fe9574a 100644 --- a/src/js/themes/styleConstants.js +++ b/src/js/themes/styleConstants.js @@ -96,4 +96,4 @@ export default { commaColor: '#666', commaFontSize: '12px', commaMarginRight: '4px' -}; +} diff --git a/test/tests/js/Index-test.js b/test/tests/js/Index-test.js index d8d22c5..ee3fdec 100644 --- a/test/tests/js/Index-test.js +++ b/test/tests/js/Index-test.js @@ -11,8 +11,6 @@ global.window = window global.document = window.document describe('', function () { - const rjvId = 1 - it('check data type labels from index', function () { const wrapper = render( ', function () { - const large_array = new Array(15).fill('test') + const largeArray = new Array(15).fill('test') it('ArrayGroup mount', function () { const wrapper = render( @@ -15,7 +15,7 @@ describe('', function () { groupArraysAfterLength={5} namespace='test' name='test' - src={large_array} + src={largeArray} theme='rjv-default' jsvRoot={false} indentWidth={4} @@ -31,7 +31,7 @@ describe('', function () { groupArraysAfterLength={5} namespace={['test']} name='test' - src={large_array} + src={largeArray} theme='rjv-default' jsvRoot={false} indentWidth={4} @@ -57,7 +57,7 @@ describe('', function () { groupArraysAfterLength={5} namespace={['test']} name='test' - src={large_array} + src={largeArray} theme='rjv-default' jsvRoot={false} indentWidth={4} @@ -72,14 +72,14 @@ describe('', function () { }) it('ArrayGroup paginates groups accurately', function () { - const test_array = new Array(17).fill('test') + const testArray = new Array(17).fill('test') const wrapper = mount( ', function () { groupArraysAfterLength={5} namespace={['test']} name='test' - src={large_array} + src={largeArray} theme='rjv-default' jsvRoot indentWidth={4} @@ -110,4 +110,32 @@ describe('', function () { expect(wrapper.find('.array-group').length).to.equal(3) }) + + it('ArrayGroup should call onSelect when clicking object key', function () { + const src = new Array(6).fill('test') + let selected = null + const wrapper = mount( + { + selected = data + }} + /> + ) + + wrapper.find('.object-key').first().simulate('click') + + expect(selected).to.deep.equal({ + name: 'items', + value: src, + type: 'array', + namespace: [] + }) + }) }) diff --git a/test/tests/js/components/CopyToClipboard-test.js b/test/tests/js/components/CopyToClipboard-test.js index 7543968..5e1f125 100644 --- a/test/tests/js/components/CopyToClipboard-test.js +++ b/test/tests/js/components/CopyToClipboard-test.js @@ -1,5 +1,5 @@ import React from 'react' -import { shallow, mount } from 'enzyme' +import { shallow } from 'enzyme' import { expect } from 'chai' import CopyToClipboard from './../../../../src/js/components/CopyToClipboard' diff --git a/test/tests/js/components/DataTypes/DataTypeLabel-test.js b/test/tests/js/components/DataTypes/DataTypeLabel-test.js index 805810d..e427959 100644 --- a/test/tests/js/components/DataTypes/DataTypeLabel-test.js +++ b/test/tests/js/components/DataTypes/DataTypeLabel-test.js @@ -10,7 +10,7 @@ describe('', function () { it('DataTypeLabel should exist when displayDataTypes is true', function () { const wrapper = shallow( ', function () { it('DataTypeLabel should not exist when displayDataTypes is false', function () { const wrapper = shallow( ', function () { const rjvId = 1 diff --git a/test/tests/js/components/DataTypes/Object-test.js b/test/tests/js/components/DataTypes/Object-test.js index 7c01c0b..29fcd4b 100644 --- a/test/tests/js/components/DataTypes/Object-test.js +++ b/test/tests/js/components/DataTypes/Object-test.js @@ -8,7 +8,7 @@ describe('', function () { const rjvId = 1 it('Object component should have a data type label', function () { - let src = { + const src = { test: true } const wrapper = shallow( @@ -19,7 +19,7 @@ describe('', function () { theme='rjv-default' indentWidth={1} depth={1} - displayDataTypes={true} + displayDataTypes type='object' /> ) @@ -27,21 +27,21 @@ describe('', function () { }) it('Object mount, multiple data type labels', function () { - let src = { - bool: true, //should have label - int: 5, //should have label - str: 'test', //should have label + const src = { + bool: true, // should have label + int: 5, // should have label + str: 'test', // should have label nan: NaN, null: null, - undefined: undefined, - func: function () {}, //should have label - float: 1.325, //should have label + undefined, + func: function () {}, // should have label + float: 1.325, // should have label arr: [ - 1, //should have label - 2 //should have label + 1, // should have label + 2 // should have label ], obj: { - test: true //should have label + test: true // should have label }, empty_arr: [], empty_obj: {} @@ -55,7 +55,7 @@ describe('', function () { indentWidth={1} depth={1} collapsed={false} - displayDataTypes={true} + displayDataTypes type='object' /> ) @@ -63,21 +63,21 @@ describe('', function () { }) it('Object mount, no data type labels when collapsed', function () { - let src = { - bool: true, //should have label - int: 5, //should have label - str: 'test', //should have label + const src = { + bool: true, // should have label + int: 5, // should have label + str: 'test', // should have label nan: NaN, null: null, - undefined: undefined, - func: function () {}, //should have label - float: 1.325, //should have label + undefined, + func: function () {}, // should have label + float: 1.325, // should have label arr: [ - 1, //should have label - 2 //should have label + 1, // should have label + 2 // should have label ], obj: { - test: true //should have label + test: true // should have label } } const wrapper = render( @@ -88,8 +88,8 @@ describe('', function () { theme='rjv-default' indentWidth={1} depth={1} - displayDataTypes={true} - collapsed={true} + displayDataTypes + collapsed type='object' /> ) @@ -97,8 +97,8 @@ describe('', function () { }) it('Array mount expanded', function () { - let src = { - arr1: [('arr2': ['test'])] + const src = { + arr1: [{ arr2: ['test'] }] } const wrapper = render( ', function () { indentWidth={1} collapsed={false} depth={1} - displayDataTypes={true} + displayDataTypes type='array' /> ) - expect(wrapper.find('.expanded-icon')).to.have.length(2) + expect(wrapper.find('.expanded-icon')).to.have.length(4) expect(wrapper.find('.collapsed-icon')).to.have.length(0) }) it('Array mount collapsed', function () { - let src = { - arr1: [('arr2': ['test'])] + const src = { + arr1: [{ arr2: ['test'] }] } const wrapper = render( ', function () { name='test' rjvId={rjvId} theme='rjv-default' - collapsed={true} + collapsed indentWidth={1} depth={1} type='array' @@ -140,8 +140,8 @@ describe('', function () { }) it('Array mount collapsed circle', function () { - let src = { - arr1: [('arr2': ['test'])] + const src = { + arr1: [{ arr2: ['test'] }] } const wrapper = render( ', function () { name='test' rjvId={rjvId} theme='rjv-default' - collapsed={true} + collapsed indentWidth={1} depth={1} type='array' @@ -161,8 +161,8 @@ describe('', function () { }) it('Array mount collapsed square', function () { - let src = { - arr1: [('arr2': ['test'])] + const src = { + arr1: [{ arr2: ['test'] }] } const wrapper = render( ', function () { name='test' rjvId={rjvId} theme='rjv-default' - collapsed={true} + collapsed indentWidth={1} depth={1} iconStyle='square' @@ -183,8 +183,8 @@ describe('', function () { }) it('Array mount collapsed triangle', function () { - let src = { - arr1: [('arr2': ['test'])] + const src = { + arr1: [{ arr2: ['test'] }] } const wrapper = render( ', function () { name='test' rjvId={rjvId} theme='rjv-default' - collapsed={true} + collapsed indentWidth={1} depth={1} iconStyle='triangle' @@ -205,7 +205,7 @@ describe('', function () { }) it('non-empty object should be expanded', function () { - let src = { test: true } + const src = { test: true } const wrapper = shallow( ', function () { }) it('empty object should not be expanded', function () { - let src = {} + const src = {} const wrapper = shallow( ', function () { }) it('non-empty array should be expanded', function () { - let src = [1, 2, 3] + const src = [1, 2, 3] const wrapper = shallow( ', function () { expect(wrapper.state('expanded')).to.equal(true) }) + it('Object should call onSelect when clicking key for object values', function () { + const src = {} + let selected = null + + const wrapper = mount( + { + selected = data + }} + /> + ) + + wrapper.find('.object-key').first().simulate('click') + + expect(selected).to.deep.equal({ + name: 'settings', + value: src, + type: 'object', + namespace: [] + }) + }) + + it('Object should call onSelect when clicking key for array values', function () { + const src = [] + let selected = null + + const wrapper = mount( + { + selected = data + }} + /> + ) + + wrapper.find('.object-key').first().simulate('click') + + expect(selected).to.deep.equal({ + name: 'items', + value: src, + type: 'array', + namespace: [] + }) + }) + it('empty array should not be expanded', function () { - let src = [] + const src = [] const wrapper = shallow( ', function () { }) it('non-empty array should have ellipsis', function () { - let src = [1, 2, 3] + const src = [1, 2, 3] const wrapper = render( ', function () { theme='rjv-default' namespace={['root']} rjvId={rjvId} - collapsed={true} + collapsed indentWidth={1} /> ) @@ -281,7 +340,7 @@ describe('', function () { }) it('empty array should not have ellipsis', function () { - let src = [] + const src = [] const wrapper = render( ', function () { theme='rjv-default' namespace={['root']} rjvId={rjvId} - collapsed={true} + collapsed indentWidth={1} /> ) @@ -298,7 +357,7 @@ describe('', function () { }) it('should collapse at shouldCollapse logic', function () { - let src = { prop1: 1, prop2: 2, prop3: 3 } + const src = { prop1: 1, prop2: 2, prop3: 3 } const wrapper = shallow( ', function () { }) it('should expand based on shouldCollapse logic', function () { - let src = { prop1: 1, prop2: 2, prop3: 3 } + const src = { prop1: 1, prop2: 2, prop3: 3 } const wrapper = shallow( ', function () { expect(wrapper.state('expanded')).to.equal(true) }) it('sort object keys', () => { - let src = { + const src = { d: 'd', b: 'b', a: 'a', @@ -342,10 +401,10 @@ describe('', function () { src={src} theme='rjv-default' namespace={['root']} - sortKeys={true} + sortKeys collapsed={false} shouldCollapse={() => false} - quotesOnKeys={true} + quotesOnKeys indentWidth={1} /> ) @@ -353,7 +412,7 @@ describe('', function () { }) it('do not sort object keys', () => { - let src = { + const src = { d: 'd', b: 'b', a: 'a', @@ -367,7 +426,7 @@ describe('', function () { namespace={['root']} collapsed={false} shouldCollapse={() => false} - quotesOnKeys={true} + quotesOnKeys indentWidth={1} /> ) @@ -375,7 +434,7 @@ describe('', function () { }) it('Object should show comma when showComma is true and not last element', function () { - let src = { + const src = { prop1: 1, prop2: 2 } @@ -394,11 +453,13 @@ describe('', function () { type='object' /> ) - expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.true + expect( + wrapper.find('span').someWhere(node => node.text() === ',') + ).to.equal(true) }) it('Object should not show comma when showComma is false', function () { - let src = { + const src = { prop1: 1, prop2: 2 } @@ -417,11 +478,13 @@ describe('', function () { type='object' /> ) - expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false + expect( + wrapper.find('span').someWhere(node => node.text() === ',') + ).to.equal(false) }) it('Object should not show comma when isLast is true', function () { - let src = { + const src = { prop1: 1, prop2: 2 } @@ -440,11 +503,13 @@ describe('', function () { type='object' /> ) - expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false + expect( + wrapper.find('span').someWhere(node => node.text() === ',') + ).to.equal(false) }) it('Object should not show comma when jsvRoot is true', function () { - let src = { + const src = { prop1: 1, prop2: 2 } @@ -464,6 +529,8 @@ describe('', function () { type='object' /> ) - expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false + expect( + wrapper.find('span').someWhere(node => node.text() === ',') + ).to.equal(false) }) }) diff --git a/test/tests/js/components/DataTypes/Regex-test.js b/test/tests/js/components/DataTypes/Regex-test.js index c3900de..14db775 100644 --- a/test/tests/js/components/DataTypes/Regex-test.js +++ b/test/tests/js/components/DataTypes/Regex-test.js @@ -4,8 +4,6 @@ import { expect } from 'chai' import JsonRegex from './../../../../../src/js/components/DataTypes/Function' -import AttributeStore from './../../../../../src/js/stores/ObjectAttributes' - describe('', function () { const rjvId = 1 diff --git a/test/tests/js/components/ObjectKeyModal/AddKeyRequest-test.js b/test/tests/js/components/ObjectKeyModal/AddKeyRequest-test.js index 06d11ed..4e44adc 100644 --- a/test/tests/js/components/ObjectKeyModal/AddKeyRequest-test.js +++ b/test/tests/js/components/ObjectKeyModal/AddKeyRequest-test.js @@ -1,5 +1,5 @@ import React from 'react' -import { shallow, render, mount } from 'enzyme' +import { mount } from 'enzyme' import { expect } from 'chai' import AddKeyRequest from './../../../../../src/js/components/ObjectKeyModal/AddKeyRequest' diff --git a/test/tests/js/components/ObjectKeyModal/ObjectKeyModal-test.js b/test/tests/js/components/ObjectKeyModal/ObjectKeyModal-test.js index 93169b5..b90d7c2 100644 --- a/test/tests/js/components/ObjectKeyModal/ObjectKeyModal-test.js +++ b/test/tests/js/components/ObjectKeyModal/ObjectKeyModal-test.js @@ -1,5 +1,5 @@ import React from 'react' -import { shallow, render, mount } from 'enzyme' +import { mount } from 'enzyme' import { expect } from 'chai' import ObjectKeyModal from './../../../../../src/js/components/ObjectKeyModal/ObjectKeyModal' @@ -32,12 +32,12 @@ describe('', function () { }) it('ObjectKeyModal invalid input', function () { - let valid_counter = 0 + let validCounter = 0 const wrapper = mount( { - valid_counter++ + validCounter++ return input !== 'invalid' }} submit={() => { @@ -57,11 +57,11 @@ describe('', function () { expect(wrapper.find('.key-modal-input').props().value).to.equal('invalid') expect(wrapper.find('.key-modal-submit').length).to.equal(0) // initial validation plus simluated input change - expect(valid_counter).to.equal(2) + expect(validCounter).to.equal(2) }) it('ObjectKeyModal test submit', function () { - let submit_counter = 0 + let submitCounter = 0 const wrapper = mount( ', function () { }} submit={input => { expect(input).to.equal('test') - submit_counter++ + submitCounter++ return true }} theme='rjv-default' @@ -80,7 +80,7 @@ describe('', function () { expect(wrapper.find('.key-modal-submit').length).to.equal(2) wrapper.find('.key-modal-submit').first().simulate('click') - expect(submit_counter).to.equal(1) + expect(submitCounter).to.equal(1) }) it('ObjectKeyModal simulate modal close click', function () { @@ -125,7 +125,7 @@ describe('', function () { }) it('ObjectKeyModal submit with Enter key press', function () { - let submit_counter = 0 + let submitCounter = 0 const wrapper = mount( ', function () { return true }} submit={() => { - submit_counter++ + submitCounter++ return true }} theme='rjv-default' @@ -144,12 +144,12 @@ describe('', function () { expect(wrapper.find('.key-modal-input').length).to.equal(1) wrapper.find('.key-modal-input').simulate('keyPress', { key: 'Enter' }) - expect(submit_counter).to.equal(1) + expect(submitCounter).to.equal(1) expect(wrapper.state('input')).to.equal('test') }) it('ObjectKeyModal close with Escape', function () { - let submit_counter = 0 + let submitCounter = 0 const wrapper = mount( ', function () { return true }} submit={() => { - submit_counter++ + submitCounter++ return true }} theme='rjv-default' @@ -168,7 +168,7 @@ describe('', function () { expect(wrapper.find('.key-modal-input').length).to.equal(1) wrapper.find('.key-modal-input').simulate('keyPress', { key: 'Escape' }) - expect(submit_counter).to.equal(0) + expect(submitCounter).to.equal(0) expect(wrapper.state('input')).to.equal('test') }) }) diff --git a/test/tests/js/components/ToggleIcons-test.js b/test/tests/js/components/ToggleIcons-test.js index 3dbe48f..769d9cc 100644 --- a/test/tests/js/components/ToggleIcons-test.js +++ b/test/tests/js/components/ToggleIcons-test.js @@ -1,5 +1,5 @@ import React from 'react' -import { render, shallow } from 'enzyme' +import { shallow } from 'enzyme' import { expect } from 'chai' import { diff --git a/test/tests/js/components/VariableEditor-test.js b/test/tests/js/components/VariableEditor-test.js index 075a998..408bc9e 100644 --- a/test/tests/js/components/VariableEditor-test.js +++ b/test/tests/js/components/VariableEditor-test.js @@ -1,8 +1,7 @@ import React from 'react' -import { shallow, render, mount } from 'enzyme' +import { shallow } from 'enzyme' import { expect } from 'chai' -import Index from './../../../../src/js/index' import VariableEditor from './../../../../src/js/components/VariableEditor' describe('', function () { @@ -13,7 +12,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} singleIndent={1} variable={{ @@ -48,7 +47,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -61,12 +60,40 @@ describe('', function () { expect(wrapper.find('.click-to-edit')).to.have.length(0) }) + it('VariableEditor should call onSelect when clicking object key', function () { + let selected = null + const wrapper = shallow( + { + selected = data + }} + keyModifier={() => false} + namespace={['root', 'parent']} + rjvId={rjvId} + variable={{ + name: 'test', + value: 5, + type: 'int' + }} + /> + ) + wrapper.find('.object-key').simulate('click') + expect(selected).to.deep.equal({ + name: 'test', + value: 5, + type: 'int', + namespace: ['parent'] + }) + }) + it('VariableEditor test textarea and cancel icon', function () { const wrapper = shallow( { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -84,20 +111,20 @@ describe('', function () { }) it('VariableEditor test textarea and submit icon', function () { - const existing_value = 'existing_value' - const new_value = 'new_value' + const existingValue = 'existing_value' + const newValue = 'new_value' const wrapper = shallow( { - expect(edit.updated_src.test).to.equal(new_value) + expect(edit.updated_src.test).to.equal(newValue) }} namespace={['test']} rjvId={rjvId} variable={{ name: 'test', - value: existing_value, + value: existingValue, type: 'string' }} /> @@ -111,10 +138,10 @@ describe('', function () { expect(wrapper.state('editMode')).to.equal(true) // make sure default textarea value is correct expect(wrapper.find('.variable-editor').props().value).to.equal( - existing_value + existingValue ) // update edit value - wrapper.setState({ editValue: new_value }) + wrapper.setState({ editValue: newValue }) // submit new value wrapper.find('.edit-check').simulate('click') // make sure editMode is off after submit @@ -122,20 +149,20 @@ describe('', function () { }) it('VariableEditor edit after src change should respect current src', function () { - const existing_value = 'existing_value' - const new_value = 'new_value' + const existingValue = 'existing_value' + const newValue = 'new_value' const wrapper = shallow( { - expect(edit.updated_src.test).to.equal(new_value) + expect(edit.updated_src.test).to.equal(newValue) }} namespace={['test']} rjvId={rjvId} variable={{ name: 'test', - value: existing_value, + value: existingValue, type: 'string' }} /> @@ -149,10 +176,10 @@ describe('', function () { expect(wrapper.state('editMode')).to.equal(true) // make sure default textarea value is correct expect(wrapper.find('.variable-editor').props().value).to.equal( - existing_value + existingValue ) // update edit value - wrapper.setState({ editValue: new_value }) + wrapper.setState({ editValue: newValue }) // cancel update wrapper.find('.edit-cancel').simulate('click') // make sure editMode is off after cancel @@ -163,7 +190,7 @@ describe('', function () { expect(wrapper.state('editMode')).to.equal(true) // make sure that textarea still contains original value expect(wrapper.find('.variable-editor').props().value).to.equal( - existing_value + existingValue ) }) @@ -172,7 +199,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -192,7 +219,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -212,7 +239,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -232,7 +259,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -252,7 +279,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -274,7 +301,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -294,7 +321,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -314,7 +341,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -334,7 +361,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: 'test', @@ -354,7 +381,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} variable={{ name: '\\\n\t\r\f\\n', @@ -378,7 +405,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} showComma isLast={false} @@ -389,7 +416,9 @@ describe('', function () { }} /> ) - expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.true + expect( + wrapper.find('span').someWhere(node => node.text() === ',') + ).to.equal(true) }) it('VariableEditor should not show comma when showComma is false', function () { @@ -397,7 +426,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} showComma={false} isLast={false} @@ -408,7 +437,9 @@ describe('', function () { }} /> ) - expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false + expect( + wrapper.find('span').someWhere(node => node.text() === ',') + ).to.equal(false) }) it('VariableEditor should not show comma when isLast is true', function () { @@ -416,7 +447,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} showComma isLast @@ -427,7 +458,9 @@ describe('', function () { }} /> ) - expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.false + expect( + wrapper.find('span').someWhere(node => node.text() === ',') + ).to.equal(false) }) it('VariableEditor should render comma before tools when showComma is true', function () { @@ -435,7 +468,7 @@ describe('', function () { { }} + onEdit={edit => {}} rjvId={rjvId} showComma isLast={false} @@ -446,10 +479,12 @@ describe('', function () { }} /> ) - + // Check that comma exists - expect(wrapper.find('span').someWhere(node => node.text() === ',')).to.be.true - + expect( + wrapper.find('span').someWhere(node => node.text() === ',') + ).to.equal(true) + // Check that tools (edit icon) exist const editIcon = wrapper.find('.click-to-edit-icon') expect(editIcon).to.have.length(1) diff --git a/test/tests/js/components/VariableMeta-test.js b/test/tests/js/components/VariableMeta-test.js index 139fa6b..11b9caf 100644 --- a/test/tests/js/components/VariableMeta-test.js +++ b/test/tests/js/components/VariableMeta-test.js @@ -53,18 +53,18 @@ describe('', function () { }) it('VariableMeta clipboard click with copy callback', function () { - const input_src = { test: true } - let callback_counter = 0 + const inputSrc = { test: true } + let callbackCounter = 0 const wrapper = mount( { - expect(copy.src.test).to.equal(input_src.test) + expect(copy.src.test).to.equal(inputSrc.test) // increment counter to assert that callback was called - callback_counter++ + callbackCounter++ }} onAdd={false} onDelete={false} @@ -77,7 +77,7 @@ describe('', function () { document.execCommand = mock => {} wrapper.find('.copy-icon').first().simulate('click') // verify that callback was called - expect(callback_counter).to.equal(1) + expect(callbackCounter).to.equal(1) }) it('VariableMeta clipboard click without copy callback', function () { diff --git a/test/tests/js/components/icons-test.js b/test/tests/js/components/icons-test.js index d98b8c2..f62ef84 100644 --- a/test/tests/js/components/icons-test.js +++ b/test/tests/js/components/icons-test.js @@ -1,8 +1,7 @@ import React from 'react' -import { shallow, render, mount } from 'enzyme' +import { shallow } from 'enzyme' import { expect } from 'chai' -import Index from './../../../../src/js/index' import { CircleMinus, CirclePlus, diff --git a/test/tests/js/helpers/Util-test.js b/test/tests/js/helpers/Util-test.js index 19d51ba..b2a5703 100644 --- a/test/tests/js/helpers/Util-test.js +++ b/test/tests/js/helpers/Util-test.js @@ -1,7 +1,10 @@ -import React from 'react' import { expect } from 'chai' -import { toType, isTheme, escapeString } from './../../../../src/js/helpers/util' +import { + toType, + isTheme, + escapeString +} from './../../../../src/js/helpers/util' describe('toType', function () { it('toType object', function () { @@ -30,7 +33,7 @@ describe('toType', function () { }) it('toType function', function () { - const test = () => { } + const test = () => {} expect(toType(test)).to.equal('function') }) diff --git a/test/tests/js/helpers/parseInput-test.js b/test/tests/js/helpers/parseInput-test.js index bf3d0c3..ee84511 100644 --- a/test/tests/js/helpers/parseInput-test.js +++ b/test/tests/js/helpers/parseInput-test.js @@ -1,4 +1,3 @@ -import React from 'react' import { expect } from 'chai' import parseInput from './../../../../src/js/helpers/parseInput' diff --git a/test/tests/js/helpers/stringifyVariable-test.js b/test/tests/js/helpers/stringifyVariable-test.js index aa11517..78d7132 100644 --- a/test/tests/js/helpers/stringifyVariable-test.js +++ b/test/tests/js/helpers/stringifyVariable-test.js @@ -1,4 +1,3 @@ -import React from 'react' import { expect } from 'chai' import stringifyVariable from './../../../../src/js/helpers/stringifyVariable' diff --git a/test/tests/js/stores/ObjectAttributes-test.js b/test/tests/js/stores/ObjectAttributes-test.js index 7aad544..1405bb1 100644 --- a/test/tests/js/stores/ObjectAttributes-test.js +++ b/test/tests/js/stores/ObjectAttributes-test.js @@ -1,5 +1,3 @@ -import React from 'react' -import { shallow } from 'enzyme' import { expect } from 'chai' import ObjectAttributes from './../../../../src/js/stores/ObjectAttributes' diff --git a/test/tests/js/themes/getStyle-test.js b/test/tests/js/themes/getStyle-test.js index 566542d..8287aac 100644 --- a/test/tests/js/themes/getStyle-test.js +++ b/test/tests/js/themes/getStyle-test.js @@ -1,12 +1,8 @@ -import React from 'react' -import { shallow } from 'enzyme' import { expect } from 'chai' import getStyle from './../../../../src/js/themes/getStyle' describe('getStyle', function () { - const rjvId = 1 - it('test that style is returned', function () { const style = getStyle('rjv-default', 'app-container') expect(style.style.cursor).to.equal('default') @@ -14,16 +10,16 @@ describe('getStyle', function () { it('test objectKeyVal return', function () { const style = getStyle('rjv-default', 'objectKeyVal', { paddingLeft: 10 }) - expect(style.style).to.exist + expect(style.style).to.not.equal(undefined) }) it('test "none" theme', function () { const style = getStyle('none', 'app-container') - expect(style.style).to.exist + expect(style.style).to.not.equal(undefined) }) it('test theme not set (NOTICE OUTPUT EXPECTED)', function () { const style = getStyle(false, 'app-container') - expect(style.style).to.exist + expect(style.style).to.not.equal(undefined) }) }) diff --git a/webpack/webpack.config.js b/webpack/webpack.config.js index df609ae..4bf03e5 100644 --- a/webpack/webpack.config.js +++ b/webpack/webpack.config.js @@ -1,5 +1,4 @@ const path = require('path') -const webpack = require('webpack') const TerserPlugin = require('terser-webpack-plugin') const PATHS = {