Created context menu button. Some refactoring
This commit is contained in:
parent
fda4f94655
commit
37ae2111ee
|
@ -38,6 +38,7 @@
|
|||
"gulp-shell": "0.5.2",
|
||||
"gulp-util": "3.0.7",
|
||||
"json-loader": "0.5.4",
|
||||
"json-pointer": "0.5.0",
|
||||
"mithril": "0.2.5",
|
||||
"mkdirp": "0.5.1",
|
||||
"mocha": "2.4.5",
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import { h, Component } from 'preact'
|
||||
|
||||
export default class ContextMenu extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
render () {
|
||||
return h('div', {class: 'jsoneditor-contextmenu'}, 'context menu...')
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
import { h, Component } from 'preact'
|
||||
|
||||
import ContextMenu from './ContextMenu'
|
||||
import { escapeHTML, unescapeHTML } from './utils/stringUtils'
|
||||
import { getInnerText } from './utils/domUtils'
|
||||
import {stringConvert, valueType, isUrl} from './utils/typeUtils'
|
||||
|
@ -13,6 +15,7 @@ export default class JSONNode extends Component {
|
|||
this.handleClickValue = this.handleClickValue.bind(this)
|
||||
this.handleKeyDownValue = this.handleKeyDownValue.bind(this)
|
||||
this.handleExpand = this.handleExpand.bind(this)
|
||||
this.handleContextMenu = this.handleContextMenu.bind(this)
|
||||
}
|
||||
|
||||
render (props) {
|
||||
|
@ -27,13 +30,14 @@ export default class JSONNode extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
renderJSONObject ({data, index, options, onChangeValue, onChangeProperty, onExpand}) {
|
||||
renderJSONObject ({data, index, options, events}) {
|
||||
const childCount = data.childs.length
|
||||
const contents = [
|
||||
h('div', {class: 'jsoneditor-node jsoneditor-object'}, [
|
||||
this.renderExpandButton(),
|
||||
this.renderContextMenuButton(),
|
||||
this.renderProperty(data, index, options),
|
||||
this.renderSeparator(),
|
||||
this.renderSeparator(), // TODO: remove separator for Object and Array (gives an issue in Preact)
|
||||
this.renderReadonly(`{${childCount}}`, `Array containing ${childCount} items`)
|
||||
])
|
||||
]
|
||||
|
@ -43,9 +47,7 @@ export default class JSONNode extends Component {
|
|||
return h(JSONNode, {
|
||||
data: child,
|
||||
options,
|
||||
onChangeValue,
|
||||
onChangeProperty,
|
||||
onExpand
|
||||
events
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -55,13 +57,14 @@ export default class JSONNode extends Component {
|
|||
return h('li', {}, contents)
|
||||
}
|
||||
|
||||
renderJSONArray ({data, index, options, onChangeValue, onChangeProperty, onExpand}) {
|
||||
renderJSONArray ({data, index, options, events}) {
|
||||
const childCount = data.childs.length
|
||||
const contents = [
|
||||
h('div', {class: 'jsoneditor-node jsoneditor-array'}, [
|
||||
this.renderExpandButton(),
|
||||
this.renderContextMenuButton(),
|
||||
this.renderProperty(data, index, options),
|
||||
this.renderSeparator(),
|
||||
this.renderSeparator(), // TODO: remove separator for Object and Array (gives an issue in Preact)
|
||||
this.renderReadonly(`[${childCount}]`, `Array containing ${childCount} items`)
|
||||
])
|
||||
]
|
||||
|
@ -72,9 +75,7 @@ export default class JSONNode extends Component {
|
|||
data: child,
|
||||
index,
|
||||
options,
|
||||
onChangeValue,
|
||||
onChangeProperty,
|
||||
onExpand
|
||||
events
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -88,6 +89,7 @@ export default class JSONNode extends Component {
|
|||
return h('li', {}, [
|
||||
h('div', {class: 'jsoneditor-node'}, [
|
||||
h('div', {class: 'jsoneditor-button-placeholder'}),
|
||||
this.renderContextMenuButton(),
|
||||
this.renderProperty(data, index, options),
|
||||
this.renderSeparator(),
|
||||
this.renderValue(data.value)
|
||||
|
@ -116,14 +118,6 @@ export default class JSONNode extends Component {
|
|||
}, content)
|
||||
}
|
||||
|
||||
static _rootName (data, options) {
|
||||
return typeof options.name === 'string'
|
||||
? options.name
|
||||
: (data.type === 'object' || data.type === 'array')
|
||||
? data.type
|
||||
: valueType(data.value)
|
||||
}
|
||||
|
||||
renderSeparator() {
|
||||
return h('div', {class: 'jsoneditor-separator'}, ':')
|
||||
}
|
||||
|
@ -151,22 +145,41 @@ export default class JSONNode extends Component {
|
|||
)
|
||||
}
|
||||
|
||||
renderContextMenuButton () {
|
||||
const childs = this.props.data.menu ? [
|
||||
h(ContextMenu)
|
||||
] : null
|
||||
|
||||
const className = `jsoneditor-button jsoneditor-contextmenu`
|
||||
return h('div', {class: 'jsoneditor-button-container'},
|
||||
h('button', {class: className, onClick: this.handleContextMenu}, childs)
|
||||
)
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
return Object.keys(nextProps).some(prop => this.props[prop] !== nextProps[prop])
|
||||
}
|
||||
|
||||
static _rootName (data, options) {
|
||||
return typeof options.name === 'string'
|
||||
? options.name
|
||||
: (data.type === 'object' || data.type === 'array')
|
||||
? data.type
|
||||
: valueType(data.value)
|
||||
}
|
||||
|
||||
handleChangeProperty (event) {
|
||||
const property = unescapeHTML(getInnerText(event.target))
|
||||
const oldPath = this.props.data.path
|
||||
const newPath = oldPath.slice(0, oldPath.length - 1).concat(property)
|
||||
|
||||
this.props.onChangeProperty(oldPath, newPath)
|
||||
this.props.events.onChangeProperty(oldPath, newPath)
|
||||
}
|
||||
|
||||
handleChangeValue (event) {
|
||||
const value = this._getValueFromEvent(event)
|
||||
|
||||
this.props.onChangeValue(this.props.data.path, value)
|
||||
this.props.events.onChangeValue(this.props.data.path, value)
|
||||
}
|
||||
|
||||
handleClickValue (event) {
|
||||
|
@ -182,7 +195,11 @@ export default class JSONNode extends Component {
|
|||
}
|
||||
|
||||
handleExpand (event) {
|
||||
this.props.onExpand(this.props.data.path, !this.props.data.expanded)
|
||||
this.props.events.onExpand(this.props.data.path, !this.props.data.expanded)
|
||||
}
|
||||
|
||||
handleContextMenu (event) {
|
||||
this.props.events.onContextMenu(this.props.data.path, !this.props.data.menu)
|
||||
}
|
||||
|
||||
_openLinkIfUrl (event) {
|
||||
|
|
33
src/Main.js
33
src/Main.js
|
@ -20,24 +20,25 @@ export default class Main extends Component {
|
|||
expanded: true,
|
||||
path: [],
|
||||
childs: []
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
this._onExpand = this._onExpand.bind(this)
|
||||
this._onChangeValue = this._onChangeValue.bind(this)
|
||||
this._onChangeProperty = this._onChangeProperty.bind(this)
|
||||
events: {
|
||||
onChangeProperty: this._onChangeProperty.bind(this),
|
||||
onChangeValue: this._onChangeValue.bind(this),
|
||||
onExpand: this._onExpand.bind(this),
|
||||
onContextMenu: this._onContextMenu.bind(this)
|
||||
},
|
||||
|
||||
menu: null,
|
||||
|
||||
search: null
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return h('div', {class: 'jsoneditor'}, [
|
||||
h('ul', {class: 'jsoneditor-list'}, [
|
||||
h(JSONNode, {
|
||||
data: this.state.data,
|
||||
options: this.state.options,
|
||||
onChangeProperty: this._onChangeProperty,
|
||||
onChangeValue: this._onChangeValue,
|
||||
onExpand: this._onExpand
|
||||
})
|
||||
h(JSONNode, this.state)
|
||||
])
|
||||
])
|
||||
}
|
||||
|
@ -70,6 +71,14 @@ export default class Main extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
_onContextMenu(path, visible) {
|
||||
const modelPath = Main._pathToModelPath(this.state.data, path).concat('menu')
|
||||
|
||||
this.setState({
|
||||
data: setIn(this.state.data, modelPath, visible)
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: comment
|
||||
get () {
|
||||
return Main._modelToJson(this.state.data)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
ul.jsoneditor-list {
|
||||
list-style-type: none;
|
||||
padding-left: 24px;
|
||||
padding-left: 20px;
|
||||
margin: 0;
|
||||
font-size: 0;
|
||||
}
|
||||
|
@ -128,6 +128,7 @@ div.jsoneditor-value.jsoneditor-url {
|
|||
}
|
||||
|
||||
button.jsoneditor-button {
|
||||
position: relative;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
|
@ -155,3 +156,24 @@ button.jsoneditor-button.jsoneditor-collapsed {
|
|||
button.jsoneditor-button.jsoneditor-expanded {
|
||||
background-position: -2px -74px;
|
||||
}
|
||||
|
||||
button.jsoneditor-button.jsoneditor-contextmenu {
|
||||
background-position: -50px -74px;
|
||||
}
|
||||
|
||||
button.jsoneditor-button.jsoneditor-contextmenu:hover,
|
||||
button.jsoneditor-button.jsoneditor-contextmenu:focus,
|
||||
button.jsoneditor-button.jsoneditor-contextmenu.jsoneditor-selected {
|
||||
background-position: -50px -50px;
|
||||
}
|
||||
|
||||
div.jsoneditor-contextmenu {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 0;
|
||||
|
||||
z-index: 1;
|
||||
background: white;
|
||||
padding: 5px;
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* @typedef {{
|
||||
* type: string,
|
||||
* expanded: boolean?,
|
||||
* menu: boolean?,
|
||||
* path: Array.<string | number>,
|
||||
* value: *?,
|
||||
* childs: Model[]?
|
||||
|
|
Loading…
Reference in New Issue