diff --git a/src/js/JSONEditor.js b/src/js/JSONEditor.js index ba38d29f0..572a394de 100644 --- a/src/js/JSONEditor.js +++ b/src/js/JSONEditor.js @@ -64,11 +64,11 @@ if (typeof Promise === 'undefined') { * {boolean} sortObjectKeys If true, object keys are * sorted before display. * false by default. - * {function} onSelectionChange Callback method, + * {function} onSelectionChange Callback method, * triggered on node selection change * Only applicable for modes * 'tree', 'view', and 'form' - * {function} onTextSelectionChange Callback method, + * {function} onTextSelectionChange Callback method, * triggered on text selection change * Only applicable for modes * {HTMLElement} modalAnchor The anchor element to apply an @@ -162,7 +162,7 @@ JSONEditor.VALID_OPTIONS = [ 'ajv', 'schema', 'schemaRefs','templates', 'ace', 'theme', 'autocomplete', 'onChange', 'onChangeJSON', 'onChangeText', - 'onEditable', 'onError', 'onEvent', 'onModeChange', 'onValidate', + 'onEditable', 'onError', 'onEvent', 'onModeChange', 'onNodeName', 'onValidate', 'onSelectionChange', 'onTextSelectionChange', 'colorPicker', 'onColorPicker', 'timestampTag', diff --git a/src/js/Node.js b/src/js/Node.js index 713b7a6f7..7212cab4a 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -2458,13 +2458,12 @@ Node.prototype.updateDom = function (options) { // apply value to DOM var domValue = this.dom.value; if (domValue) { - var count = this.childs ? this.childs.length : 0; if (this.type == 'array') { - domValue.innerHTML = '[' + count + ']'; + this.updateNodeName(); util.addClassName(this.dom.tr, 'jsoneditor-expandable'); } else if (this.type == 'object') { - domValue.innerHTML = '{' + count + '}'; + this.updateNodeName(); util.addClassName(this.dom.tr, 'jsoneditor-expandable'); } else { @@ -4464,6 +4463,46 @@ Node.prototype._escapeJSON = function (text) { return escaped; }; +/** + * update the object name according to the callback onNodeName + * @private + */ +Node.prototype.updateNodeName = function () { + try { + var count = this.childs ? this.childs.length : 0; + var nodeName; + if (this.type === 'object' || this.type === 'array') { + nodeName = this.editor.options.onNodeName({ + path: this.getPath(), + size: count, + type: this.type + }); + this.dom.value.innerHTML = (this.type === 'object') + ? '{' + (nodeName || count) + '}' + : '[' + (nodeName || count) + ']'; + } + } + catch (err) { + console.error('Error in onNodeName callback: ', err); + } +} + +/** + * update recursively the object's and its children's name. + * @private + */ +Node.prototype.recursivelyUpdateNodeName = function () { + if (this.expanded) { + this.updateNodeName(); + if (this.childs !== 'undefined') { + var i; + for (i in this.childs) { + this.childs[i].recursivelyUpdateNodeName(); + } + } + } +} + // helper function to get the internal path of a node function getInternalPath (node) { return node.getInternalPath(); diff --git a/src/js/treemode.js b/src/js/treemode.js index b0a1cfae1..17a12b0b7 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -549,6 +549,15 @@ treemode._onChange = function () { console.error('Error in onChangeText callback: ', err); } } + + // trigger the onNodeName callback + if (this.options.onNodeName && this.node.childs) { + try { + this.node.recursivelyUpdateNodeName(); + } catch (err) { + console.error("Error in onNodeName callback: ", err); + } + } }; /** @@ -1711,8 +1720,8 @@ treemode.getSelection = function () { /** * Callback registration for selection change - * @param {selectionCallback} callback - * + * @param {selectionCallback} callback + * * @callback selectionCallback */ treemode.onSelectionChange = function (callback) { @@ -1726,7 +1735,7 @@ treemode.onSelectionChange = function (callback) { * For selecting single node send only the start parameter * For clear the selection do not send any parameter * If the nodes are not from the same level the first common parent will be selected - * @param {{path: Array.}} start object contains the path for selection start + * @param {{path: Array.}} start object contains the path for selection start * @param {{path: Array.}} end object contains the path for selection end */ treemode.setSelection = function (start, end) { @@ -1737,7 +1746,7 @@ treemode.setSelection = function (start, end) { } var nodes = this._getNodeInstancesByRange(start, end); - + nodes.forEach(function(node) { node.expandTo(); }); @@ -1746,7 +1755,7 @@ treemode.setSelection = function (start, end) { /** * Returns a set of Nodes according to a range of selection - * @param {{path: Array.}} start object contains the path for range start + * @param {{path: Array.}} start object contains the path for range start * @param {{path: Array.}=} end object contains the path for range end * @return {Array.} Node instances on the given range * @private