diff --git a/public/jsoneditor.css b/public/jsoneditor.css index 90a2b28..794a1d8 100644 --- a/public/jsoneditor.css +++ b/public/jsoneditor.css @@ -46,4 +46,10 @@ ul.jsoneditor-list { .jsoneditor-readonly { color: gray; +} + +.jsoneditor-readonly:focus, +.jsoneditor-readonly:hover { + border-color: transparent; + background-color: inherit; } \ No newline at end of file diff --git a/src/JSONNode.js b/src/JSONNode.js index 59b68c3..477bb9c 100644 --- a/src/JSONNode.js +++ b/src/JSONNode.js @@ -3,6 +3,7 @@ import isObject from './utils/isObject' import escapeHTML from './utils/escapeHTML' import unescapeHTML from './utils/unescapeHTML' import getInnerText from './utils/getInnerText' +import stringConvert from './utils/stringConvert' export default class JSONNode extends Component { constructor (props) { @@ -24,13 +25,15 @@ export default class JSONNode extends Component { } } + // TODO: reorganize the render methods, they are too large now + renderObject ({parent, field, value, onChangeValue, onChangeField}) { //console.log('JSONObject', field,value) const hasParent = parent !== null - return h('li', {class: 'jsoneditor-object'}, [ - h('div', {class: 'jsoneditor-node'}, [ - h('div', {class: 'jsoneditor-field', contentEditable: hasParent, onBlur: this.onBlurField}, hasParent ? field : 'object'), + return h('li', {}, [ + h('div', {class: 'jsoneditor-node jsoneditor-object'}, [ + h('div', {class: 'jsoneditor-field' + (hasParent ? '' : ' jsoneditor-readonly'), contentEditable: hasParent, onBlur: this.onBlurField}, hasParent ? escapeHTML(field) : 'object'), h('div', {class: 'jsoneditor-separator'}, ':'), h('div', {class: 'jsoneditor-readonly', contentEditable: false}, '{' + Object.keys(value).length + '}') ]), @@ -47,7 +50,7 @@ export default class JSONNode extends Component { return h('li', {}, [ h('div', {class: 'jsoneditor-node jsoneditor-array'}, [ - h('div', {class: 'jsoneditor-field', contentEditable: hasParent, onBlur: this.onBlurField}, hasParent ? field : 'array'), + h('div', {class: 'jsoneditor-field' + (hasParent ? '' : ' jsoneditor-readonly'), contentEditable: hasParent, onBlur: this.onBlurField}, hasParent ? escapeHTML(field) : 'array'), h('div', {class: 'jsoneditor-separator'}, ':'), h('div', {class: 'jsoneditor-readonly', contentEditable: false}, '{' + value.length + '}') ]), @@ -66,7 +69,7 @@ export default class JSONNode extends Component { h('div', {class: 'jsoneditor-node'}, [ index !== undefined ? h('div', {class: 'jsoneditor-readonly', contentEditable: false}, index) - : h('div', {class: 'jsoneditor-field', contentEditable: hasParent, onBlur: this.onBlurField}, hasParent ? field : 'value'), + : h('div', {class: 'jsoneditor-field' + (hasParent ? '' : ' jsoneditor-readonly'), contentEditable: hasParent, onBlur: this.onBlurField}, hasParent ? escapeHTML(field) : 'value'), h('div', {class: 'jsoneditor-separator'}, ':'), h('div', {class: 'jsoneditor-value', contentEditable: true, onBlur: this.onBlurValue}, escapeHTML(value)) ]) @@ -79,7 +82,7 @@ export default class JSONNode extends Component { onBlurField (event) { const path = this.props.parent.getPath() - const newField = getInnerText(event.target) + const newField = unescapeHTML(getInnerText(event.target)) const oldField = this.props.field if (newField !== oldField) { this.props.onChangeField(path, newField, oldField) @@ -88,7 +91,7 @@ export default class JSONNode extends Component { onBlurValue (event) { const path = this.getPath() - const value = unescapeHTML(getInnerText(event.target)) + const value = stringConvert(unescapeHTML(getInnerText(event.target))) if (value !== this.props.value) { this.props.onChangeValue(path, value) } diff --git a/src/utils/stringConvert.js b/src/utils/stringConvert.js new file mode 100644 index 0000000..0c0d72c --- /dev/null +++ b/src/utils/stringConvert.js @@ -0,0 +1,32 @@ + +/** + * Convert contents of a string to the correct JSON type. This can be a string, + * a number, a boolean, etc + * @param {String} str + * @return {*} castedStr + * @private + */ +export default function stringConvert (str) { + const lower = str.toLowerCase() + const num = Number(str) // will nicely fail with '123ab' + const numFloat = parseFloat(str) // will nicely fail with ' ' + + if (str == '') { + return '' + } + else if (lower == 'null') { + return null + } + else if (lower == 'true') { + return true + } + else if (lower == 'false') { + return false + } + else if (!isNaN(num) && !isNaN(numFloat)) { + return num + } + else { + return str + } +}