Some refactoring

This commit is contained in:
jos 2016-09-17 15:12:25 +02:00
parent ff7f683b11
commit d235425f36
2 changed files with 58 additions and 50 deletions

View File

@ -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
} }

View File

@ -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
} }
}
/**
function expandAll (path) { * Callback function to expand all nodes
*
* @param {Array.<string>} path
* @return {boolean}
*/
static expandAll (path) {
return true return true
} }
}