Create a function `getPath` instead of passing path via props

This commit is contained in:
jos 2016-08-06 14:08:57 +02:00
parent ab37f5ba9a
commit a065fbb09e
2 changed files with 59 additions and 25 deletions

View File

@ -57,13 +57,13 @@ export default class JSONNode extends Component {
} }
} }
renderJSONObject ({path, data, options, events}) { renderJSONObject ({prop, data, options, events}) {
const childCount = data.props.length const childCount = data.props.length
const contents = [ const contents = [
h('div', {class: 'jsoneditor-node jsoneditor-object'}, [ h('div', {class: 'jsoneditor-node jsoneditor-object'}, [
this.renderExpandButton(), this.renderExpandButton(),
this.renderContextMenuButton(), this.renderContextMenuButton(),
this.renderProperty(path, data, options), this.renderProperty(prop, data, options),
this.renderReadonly(`{${childCount}}`, `Array containing ${childCount} items`) this.renderReadonly(`{${childCount}}`, `Array containing ${childCount} items`)
]) ])
] ]
@ -71,7 +71,8 @@ export default class JSONNode extends Component {
if (data.expanded) { if (data.expanded) {
const props = data.props.map(prop => { const props = data.props.map(prop => {
return h(JSONNode, { return h(JSONNode, {
path: path.concat(prop.name), parent: this,
prop: prop.name,
data: prop.value, data: prop.value,
options, options,
events events
@ -88,13 +89,13 @@ export default class JSONNode extends Component {
return h('li', {}, contents) return h('li', {}, contents)
} }
renderJSONArray ({path, data, options, events}) { renderJSONArray ({prop, data, options, events}) {
const childCount = data.items.length const childCount = data.items.length
const contents = [ const contents = [
h('div', {class: 'jsoneditor-node jsoneditor-array'}, [ h('div', {class: 'jsoneditor-node jsoneditor-array'}, [
this.renderExpandButton(), this.renderExpandButton(),
this.renderContextMenuButton(), this.renderContextMenuButton(),
this.renderProperty(path, data, options), this.renderProperty(prop, data, options),
this.renderReadonly(`[${childCount}]`, `Array containing ${childCount} items`) this.renderReadonly(`[${childCount}]`, `Array containing ${childCount} items`)
]) ])
] ]
@ -102,7 +103,8 @@ export default class JSONNode extends Component {
if (data.expanded) { if (data.expanded) {
const items = data.items.map((child, index) => { const items = data.items.map((child, index) => {
return h(JSONNode, { return h(JSONNode, {
path: path.concat(index), parent: this,
prop: index,
data: child, data: child,
options, options,
events events
@ -119,12 +121,12 @@ export default class JSONNode extends Component {
return h('li', {}, contents) return h('li', {}, contents)
} }
renderJSONValue ({path, data, options}) { renderJSONValue ({prop, data, options}) {
return h('li', {}, [ return h('li', {}, [
h('div', {class: 'jsoneditor-node'}, [ h('div', {class: 'jsoneditor-node'}, [
this.renderPlaceholder(), this.renderPlaceholder(),
this.renderContextMenuButton(), this.renderContextMenuButton(),
this.renderProperty(path, data, options), this.renderProperty(prop, data, options),
this.renderSeparator(), this.renderSeparator(),
this.renderValue(data.value) this.renderValue(data.value)
]) ])
@ -154,9 +156,8 @@ export default class JSONNode extends Component {
return h('div', {class: 'jsoneditor-readonly', title}, text) return h('div', {class: 'jsoneditor-readonly', title}, text)
} }
renderProperty (path, data, options) { renderProperty (prop, data, options) {
if (path.length > 0) { if (prop !== null) {
const prop = last(path)
const isIndex = typeof prop === 'number' const isIndex = typeof prop === 'number'
if (isIndex) { // array item if (isIndex) { // array item
@ -239,8 +240,8 @@ export default class JSONNode extends Component {
} }
const {anchor, root} = this.state.menu const {anchor, root} = this.state.menu
const path = this.props.path const path = this.getPath()
const hasParent = path.length > 0 const hasParent = this.props.parent !== null
const type = this.props.data.type const type = this.props.data.type
const events = this.props.events const events = this.props.events
const items = [] // array with menu items const items = [] // array with menu items
@ -344,7 +345,7 @@ export default class JSONNode extends Component {
] ]
}); });
if (this.props.path !== '') { if (hasParent) {
// create duplicate button // create duplicate button
items.push({ items.push({
text: 'Duplicate', text: 'Duplicate',
@ -374,7 +375,7 @@ export default class JSONNode extends Component {
} }
const {anchor, root} = this.state.appendMenu const {anchor, root} = this.state.appendMenu
const path = this.props.path const path = this.getPath()
const events = this.props.events const events = this.props.events
const items = [] // array with menu items const items = [] // array with menu items
@ -419,9 +420,21 @@ export default class JSONNode extends Component {
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
// TODO: replace with an old fashioned for loop for some more speed let prop
return Object.keys(nextProps).some(prop => this.props[prop] !== nextProps[prop]) ||
Object.keys(nextState).some(prop => this.state[prop] !== nextState[prop]) for (prop in nextProps) {
if (nextProps.hasOwnProperty(prop) && this.props[prop] !== nextProps[prop]) {
return true
}
}
for (prop in nextState) {
if (nextState.hasOwnProperty(prop) && this.state[prop] !== nextState[prop]) {
return true
}
}
return false
} }
static _rootName (data, options) { static _rootName (data, options) {
@ -433,19 +446,17 @@ export default class JSONNode extends Component {
} }
handleChangeProperty (event) { handleChangeProperty (event) {
const oldProp = last(this.props.path) const parentPath = this.props.parent.getPath()
const oldProp = this.props.prop
const newProp = unescapeHTML(getInnerText(event.target)) const newProp = unescapeHTML(getInnerText(event.target))
// remove last entry from the path to get the path of the parent object
const parentPath = this.props.path.slice(0, this.props.path.length - 1)
this.props.events.onChangeProperty(parentPath, oldProp, newProp) this.props.events.onChangeProperty(parentPath, oldProp, newProp)
} }
handleChangeValue (event) { handleChangeValue (event) {
const value = this._getValueFromEvent(event) const value = this._getValueFromEvent(event)
this.props.events.onChangeValue(this.props.path, value) this.props.events.onChangeValue(this.getPath(), value)
} }
handleClickValue (event) { handleClickValue (event) {
@ -461,7 +472,7 @@ export default class JSONNode extends Component {
} }
handleExpand (event) { handleExpand (event) {
this.props.events.onExpand(this.props.path, !this.props.data.expanded) this.props.events.onExpand(this.getPath(), !this.props.data.expanded)
} }
handleContextMenu (event) { handleContextMenu (event) {
@ -508,6 +519,9 @@ export default class JSONNode extends Component {
} }
} }
/**
* Singleton function to hide the currently visible context menu if any.
*/
static hideContextMenu () { static hideContextMenu () {
if (activeContextMenu) { if (activeContextMenu) {
activeContextMenu.setState({ activeContextMenu.setState({
@ -534,6 +548,22 @@ export default class JSONNode extends Component {
} }
} }
/**
* Get the path of this JSONNode
* @return {Array.<string | number>}
*/
getPath () {
const path = this.props.parent
? this.props.parent.getPath()
: []
if (this.props.prop !== null) {
path.push(this.props.prop)
}
return path
}
/** /**
* Get the value of the target of an event, and convert it to it's type * Get the value of the target of an event, and convert it to it's type
* @param event * @param event

View File

@ -48,7 +48,8 @@ export default class Main extends Component {
data: this.state.data, data: this.state.data,
events: this.state.events, events: this.state.events,
options: this.state.options, options: this.state.options,
path: [] parent: null,
prop: null
}) })
]) ])
]) ])
@ -88,6 +89,7 @@ export default class Main extends Component {
}) })
} }
// TODO: change to handleInsert(path, after, type)
handleInsert (path, type) { handleInsert (path, type) {
console.log('handleInsert', path, type) console.log('handleInsert', path, type)
@ -158,6 +160,7 @@ export default class Main extends Component {
} }
} }
// TODO: change to handleDuplicate(path, prop)
handleDuplicate (path) { handleDuplicate (path) {
console.log('handleDuplicate', path) console.log('handleDuplicate', path)
@ -196,6 +199,7 @@ export default class Main extends Component {
} }
} }
// TODO: change to handleRemove(path, prop)
handleRemove (path) { handleRemove (path) {
console.log('handleRemove', path) console.log('handleRemove', path)