Some refactoring
This commit is contained in:
parent
ff7f683b11
commit
d235425f36
|
@ -37,18 +37,9 @@ export default class JSONNode extends Component {
|
||||||
menu: null, // context menu
|
menu: null, // context menu
|
||||||
appendMenu: null, // append context menu (used in placeholder of empty object/array)
|
appendMenu: null, // append context menu (used in placeholder of empty object/array)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use function bindMethods(this). Gives issues for some reason, we lose focus whilst typing
|
|
||||||
this.handleChangeProperty = this.handleChangeProperty.bind(this)
|
|
||||||
this.handleChangeValue = this.handleChangeValue.bind(this)
|
|
||||||
this.handleClickValue = this.handleClickValue.bind(this)
|
|
||||||
this.handleKeyDownValue = this.handleKeyDownValue.bind(this)
|
|
||||||
this.handleExpand = this.handleExpand.bind(this)
|
|
||||||
this.handleContextMenu = this.handleContextMenu.bind(this)
|
|
||||||
this.handleAppendContextMenu = this.handleAppendContextMenu.bind(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render (props) {
|
render (props, state) {
|
||||||
if (props.data.type === 'array') {
|
if (props.data.type === 'array') {
|
||||||
return this.renderJSONArray(props)
|
return this.renderJSONArray(props)
|
||||||
}
|
}
|
||||||
|
@ -187,7 +178,7 @@ export default class JSONNode extends Component {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// root node
|
// root node
|
||||||
const content = JSONNode._getRootName(data, options)
|
const content = JSONNode.getRootName(data, options)
|
||||||
|
|
||||||
return h('div', {
|
return h('div', {
|
||||||
class: 'jsoneditor-property jsoneditor-readonly',
|
class: 'jsoneditor-property jsoneditor-readonly',
|
||||||
|
@ -204,18 +195,18 @@ export default class JSONNode extends Component {
|
||||||
renderValue (value) {
|
renderValue (value) {
|
||||||
const escapedValue = escapeHTML(value)
|
const escapedValue = escapeHTML(value)
|
||||||
const type = valueType (value)
|
const type = valueType (value)
|
||||||
const _isUrl = isUrl(value)
|
const isUrl = isUrl(value)
|
||||||
const isEmpty = escapedValue.length === 0
|
const isEmpty = escapedValue.length === 0
|
||||||
|
|
||||||
return h('div', {
|
return h('div', {
|
||||||
class: JSONNode._getValueClass(type, _isUrl, isEmpty),
|
class: JSONNode.getValueClass(type, isUrl, isEmpty),
|
||||||
contentEditable: 'true',
|
contentEditable: 'true',
|
||||||
spellCheck: 'false',
|
spellCheck: 'false',
|
||||||
onBlur: this.handleChangeValue,
|
onBlur: this.handleChangeValue,
|
||||||
onInput: this.updateValueStyling,
|
onInput: this.updateValueStyling,
|
||||||
onClick: this.handleClickValue,
|
onClick: this.handleClickValue,
|
||||||
onKeyDown: this.handleKeyDownValue,
|
onKeyDown: this.handleKeyDownValue,
|
||||||
title: _isUrl ? URL_TITLE : null
|
title: isUrl ? URL_TITLE : null
|
||||||
}, escapedValue)
|
}, escapedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,9 +216,9 @@ export default class JSONNode extends Component {
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
updateValueStyling = (event) => {
|
updateValueStyling = (event) => {
|
||||||
const value = this._getValueFromEvent(event)
|
const value = this.getValueFromEvent(event)
|
||||||
const type = valueType (value)
|
const type = valueType (value)
|
||||||
const _isUrl = isUrl(value)
|
const isUrl = isUrl(value)
|
||||||
const isEmpty = false // not needed, our div has a border and is clearly visible
|
const isEmpty = false // not needed, our div has a border and is clearly visible
|
||||||
|
|
||||||
// find the editable div, the root
|
// find the editable div, the root
|
||||||
|
@ -236,11 +227,11 @@ export default class JSONNode extends Component {
|
||||||
target = target.parentNode
|
target = target.parentNode
|
||||||
}
|
}
|
||||||
|
|
||||||
target.className = JSONNode._getValueClass(type, _isUrl, isEmpty)
|
target.className = JSONNode.getValueClass(type, isUrl, isEmpty)
|
||||||
target.title = _isUrl ? URL_TITLE : ''
|
target.title = isUrl ? URL_TITLE : ''
|
||||||
|
|
||||||
// remove all classNames from childs (needed for IE and Edge)
|
// remove all classNames from childs (needed for IE and Edge)
|
||||||
JSONNode._removeChildClasses(target)
|
JSONNode.removeChildClasses(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -251,7 +242,7 @@ export default class JSONNode extends Component {
|
||||||
* @return {string}
|
* @return {string}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
static _getValueClass (type, isUrl, isEmpty) {
|
static getValueClass (type, isUrl, isEmpty) {
|
||||||
return 'jsoneditor-value ' +
|
return 'jsoneditor-value ' +
|
||||||
'jsoneditor-' + type +
|
'jsoneditor-' + type +
|
||||||
(isUrl ? ' jsoneditor-url' : '') +
|
(isUrl ? ' jsoneditor-url' : '') +
|
||||||
|
@ -263,13 +254,13 @@ export default class JSONNode extends Component {
|
||||||
* @param elem
|
* @param elem
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
static _removeChildClasses (elem) {
|
static removeChildClasses (elem) {
|
||||||
for (let i = 0; i < elem.childNodes.length; i++) {
|
for (let i = 0; i < elem.childNodes.length; i++) {
|
||||||
const child = elem.childNodes[i]
|
const child = elem.childNodes[i]
|
||||||
if (child.class) {
|
if (child.class) {
|
||||||
child.class = ''
|
child.class = ''
|
||||||
}
|
}
|
||||||
JSONNode._removeChildClasses(child)
|
JSONNode.removeChildClasses(child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +498,7 @@ export default class JSONNode extends Component {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
static _getRootName (data, options) {
|
static getRootName (data, options) {
|
||||||
return typeof options.name === 'string'
|
return typeof options.name === 'string'
|
||||||
? options.name
|
? options.name
|
||||||
: (data.type === 'object' || data.type === 'array')
|
: (data.type === 'object' || data.type === 'array')
|
||||||
|
@ -515,7 +506,7 @@ export default class JSONNode extends Component {
|
||||||
: valueType(data.value)
|
: valueType(data.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChangeProperty (event) {
|
handleChangeProperty = (event) => {
|
||||||
const parentPath = this.props.parent.getPath()
|
const parentPath = this.props.parent.getPath()
|
||||||
const oldProp = this.props.prop
|
const oldProp = this.props.prop
|
||||||
const newProp = unescapeHTML(getInnerText(event.target))
|
const newProp = unescapeHTML(getInnerText(event.target))
|
||||||
|
@ -525,34 +516,34 @@ export default class JSONNode extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChangeValue (event) {
|
handleChangeValue = (event) => {
|
||||||
const value = this._getValueFromEvent(event)
|
const value = this.getValueFromEvent(event)
|
||||||
|
|
||||||
if (value !== this.props.data.value) {
|
if (value !== this.props.data.value) {
|
||||||
this.props.events.onChangeValue(this.getPath(), value)
|
this.props.events.onChangeValue(this.getPath(), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClickValue (event) {
|
handleClickValue = (event) => {
|
||||||
if (event.ctrlKey && event.button === 0) { // Ctrl+Left click
|
if (event.ctrlKey && event.button === 0) { // Ctrl+Left click
|
||||||
this._openLinkIfUrl(event)
|
this.openLinkIfUrl(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDownValue (event) {
|
handleKeyDownValue = (event) => {
|
||||||
if (event.ctrlKey && event.which === 13) { // Ctrl+Enter
|
if (event.ctrlKey && event.which === 13) { // Ctrl+Enter
|
||||||
this._openLinkIfUrl(event)
|
this.openLinkIfUrl(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleExpand (event) {
|
handleExpand = (event) => {
|
||||||
const recurse = event.ctrlKey
|
const recurse = event.ctrlKey
|
||||||
const expanded = !this.props.data.expanded
|
const expanded = !this.props.data.expanded
|
||||||
|
|
||||||
this.props.events.onExpand(this.getPath(), expanded, recurse)
|
this.props.events.onExpand(this.getPath(), expanded, recurse)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleContextMenu (event) {
|
handleContextMenu = (event) => {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
||||||
if (this.state.menu) {
|
if (this.state.menu) {
|
||||||
|
@ -567,14 +558,14 @@ export default class JSONNode extends Component {
|
||||||
this.setState({
|
this.setState({
|
||||||
menu: {
|
menu: {
|
||||||
anchor: event.target,
|
anchor: event.target,
|
||||||
root: JSONNode._findRootElement(event)
|
root: JSONNode.findRootElement(event)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
activeContextMenu = this
|
activeContextMenu = this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAppendContextMenu(event) {
|
handleAppendContextMenu = (event) => {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
||||||
if (this.state.appendMenu) {
|
if (this.state.appendMenu) {
|
||||||
|
@ -589,7 +580,7 @@ export default class JSONNode extends Component {
|
||||||
this.setState({
|
this.setState({
|
||||||
appendMenu: {
|
appendMenu: {
|
||||||
anchor: event.target,
|
anchor: event.target,
|
||||||
root: JSONNode._findRootElement(event)
|
root: JSONNode.findRootElement(event)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
activeContextMenu = this
|
activeContextMenu = this
|
||||||
|
@ -614,8 +605,8 @@ export default class JSONNode extends Component {
|
||||||
* @param event
|
* @param event
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_openLinkIfUrl (event) {
|
openLinkIfUrl (event) {
|
||||||
const value = this._getValueFromEvent(event)
|
const value = this.getValueFromEvent(event)
|
||||||
|
|
||||||
if (isUrl(value)) {
|
if (isUrl(value)) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
@ -647,7 +638,7 @@ export default class JSONNode extends Component {
|
||||||
* @return {string | number | boolean | null}
|
* @return {string | number | boolean | null}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_getValueFromEvent (event) {
|
getValueFromEvent (event) {
|
||||||
const stringValue = unescapeHTML(getInnerText(event.target))
|
const stringValue = unescapeHTML(getInnerText(event.target))
|
||||||
return this.props.data.type === 'string'
|
return this.props.data.type === 'string'
|
||||||
? stringValue
|
? stringValue
|
||||||
|
@ -661,7 +652,7 @@ export default class JSONNode extends Component {
|
||||||
* @return {*}
|
* @return {*}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
static _findRootElement (event) {
|
static findRootElement (event) {
|
||||||
function isEditorElement (elem) {
|
function isEditorElement (elem) {
|
||||||
return elem.className.split(' ').indexOf('jsoneditor') !== -1
|
return elem.className.split(' ').indexOf('jsoneditor') !== -1
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,30 +89,37 @@ export default class TreeMode extends Component {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleChangeValue = (path, value) => {
|
handleChangeValue = (path, value) => {
|
||||||
this.handlePatch(changeValue(this.state.data, path, value))
|
this.handlePatch(changeValue(this.state.data, path, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleChangeProperty = (parentPath, oldProp, newProp) => {
|
handleChangeProperty = (parentPath, oldProp, newProp) => {
|
||||||
this.handlePatch(changeProperty(this.state.data, parentPath, oldProp, newProp))
|
this.handlePatch(changeProperty(this.state.data, parentPath, oldProp, newProp))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleChangeType = (path, type) => {
|
handleChangeType = (path, type) => {
|
||||||
this.handlePatch(changeType(this.state.data, path, type))
|
this.handlePatch(changeType(this.state.data, path, type))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleInsert = (path, type) => {
|
handleInsert = (path, type) => {
|
||||||
this.handlePatch(insert(this.state.data, path, type))
|
this.handlePatch(insert(this.state.data, path, type))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleAppend = (parentPath, type) => {
|
handleAppend = (parentPath, type) => {
|
||||||
this.handlePatch(append(this.state.data, parentPath, type))
|
this.handlePatch(append(this.state.data, parentPath, type))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleDuplicate = (path) => {
|
handleDuplicate = (path) => {
|
||||||
this.handlePatch(duplicate(this.state.data, path))
|
this.handlePatch(duplicate(this.state.data, path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleRemove = (path) => {
|
handleRemove = (path) => {
|
||||||
const patch = [{
|
const patch = [{
|
||||||
op: 'remove',
|
op: 'remove',
|
||||||
|
@ -122,10 +129,12 @@ export default class TreeMode extends Component {
|
||||||
this.handlePatch(patch)
|
this.handlePatch(patch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleSort = (path, order = null) => {
|
handleSort = (path, order = null) => {
|
||||||
this.handlePatch(sort(this.state.data, path, order))
|
this.handlePatch(sort(this.state.data, path, order))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleExpand = (path, expanded, recurse) => {
|
handleExpand = (path, expanded, recurse) => {
|
||||||
if (recurse) {
|
if (recurse) {
|
||||||
const dataPath = toDataPath(this.state.data, path)
|
const dataPath = toDataPath(this.state.data, path)
|
||||||
|
@ -143,32 +152,34 @@ export default class TreeMode extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleExpandAll = () => {
|
handleExpandAll = () => {
|
||||||
const expanded = true
|
const expanded = true
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
data: expand(this.state.data, expandAll, expanded)
|
data: expand(this.state.data, TreeMode.expandAll, expanded)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @private */
|
||||||
handleCollapseAll = () => {
|
handleCollapseAll = () => {
|
||||||
const expanded = false
|
const expanded = false
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
data: expand(this.state.data, expandAll, expanded)
|
data: expand(this.state.data, TreeMode.expandAll, expanded)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a JSONPatch to the current JSON document and emit a change event
|
* Apply a JSONPatch to the current JSON document and emit a change event
|
||||||
* @param {JSONPatch} actions
|
* @param {JSONPatch} actions
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
// TODO: rename all handle* methods to _handle*
|
|
||||||
handlePatch = (actions) => {
|
handlePatch = (actions) => {
|
||||||
// apply changes
|
// apply changes
|
||||||
const revert = this.patch(actions)
|
const revert = this.patch(actions)
|
||||||
|
|
||||||
this._emitOnChange (actions, revert)
|
this.emitOnChange (actions, revert)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,7 +188,7 @@ export default class TreeMode extends Component {
|
||||||
* @param {JSONPatch} revert
|
* @param {JSONPatch} revert
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_emitOnChange (patch, revert) {
|
emitOnChange (patch, revert) {
|
||||||
if (this.props.options && this.props.options.onChange) {
|
if (this.props.options && this.props.options.onChange) {
|
||||||
this.props.options.onChange(patch, revert)
|
this.props.options.onChange(patch, revert)
|
||||||
}
|
}
|
||||||
|
@ -205,7 +216,7 @@ export default class TreeMode extends Component {
|
||||||
historyIndex: historyIndex + 1
|
historyIndex: historyIndex + 1
|
||||||
})
|
})
|
||||||
|
|
||||||
this._emitOnChange (historyItem.undo, historyItem.redo)
|
this.emitOnChange (historyItem.undo, historyItem.redo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +234,7 @@ export default class TreeMode extends Component {
|
||||||
historyIndex
|
historyIndex
|
||||||
})
|
})
|
||||||
|
|
||||||
this._emitOnChange (historyItem.redo, historyItem.undo)
|
this.emitOnChange (historyItem.redo, historyItem.undo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,9 +325,15 @@ export default class TreeMode extends Component {
|
||||||
return path.length === 0
|
return path.length === 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback function to expand all nodes
|
||||||
|
*
|
||||||
|
* @param {Array.<string>} path
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
static expandAll (path) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function expandAll (path) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue