From af576efb51a4a1edd3c66d14a7f26f24c0b4192b Mon Sep 17 00:00:00 2001 From: Christian Romeyke Date: Tue, 22 Nov 2016 01:05:33 +0100 Subject: [PATCH 1/7] Customize object names --- src/js/JSONEditor.js | 2 +- src/js/Node.js | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/js/JSONEditor.js b/src/js/JSONEditor.js index 7420d4951..94186b2f0 100644 --- a/src/js/JSONEditor.js +++ b/src/js/JSONEditor.js @@ -81,7 +81,7 @@ function JSONEditor (container, options, json) { var VALID_OPTIONS = [ 'ace', 'theme', 'ajv', 'schema', - 'onChange', 'onEditable', 'onError', 'onModeChange', + 'onChange', 'onEditable', 'onError', 'onModeChange', 'onObjectName', 'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys' ]; diff --git a/src/js/Node.js b/src/js/Node.js index 8a6d0fa1c..9a224d562 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -1952,7 +1952,14 @@ Node.prototype.updateDom = function (options) { util.addClassName(this.dom.tr, 'jsoneditor-expandable'); } else if (this.type == 'object') { - domValue.innerHTML = '{' + count + '}'; + var objName; + if (typeof this.editor.options.onObjectName === 'function') { + objName = this.editor.options.onObjectName({ + path: this.getPath(), + children: this.childs + }); + } + domValue.innerHTML = '{' + (objName || count) + '}'; util.addClassName(this.dom.tr, 'jsoneditor-expandable'); } else { From 4d4a45d73a609db583062960233cdbfec0d9edb6 Mon Sep 17 00:00:00 2001 From: bnanchen Date: Thu, 20 Dec 2018 15:54:12 +0100 Subject: [PATCH 2/7] Fix: the object's name updates when its properties change --- src/js/JSONEditor.js | 2 +- src/js/treemode.js | 51 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/js/JSONEditor.js b/src/js/JSONEditor.js index 9a283d525..673c466ff 100644 --- a/src/js/JSONEditor.js +++ b/src/js/JSONEditor.js @@ -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', 'onObjectName', 'onValidate', 'onSelectionChange', 'onTextSelectionChange', 'colorPicker', 'onColorPicker', 'timestampTag', diff --git a/src/js/treemode.js b/src/js/treemode.js index b0a1cfae1..5af7409eb 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -549,6 +549,47 @@ treemode._onChange = function () { console.error('Error in onChangeText callback: ', err); } } + + // trigger the onObjectName callback + if (this.options.onObjectName && this.node.childs) { + try { + var i; + var expandedNodes = []; + for (i in this.node.childs) { + if (this.node.childs[i].expanded) { + var expandedNodes = getExpandedNodes(this.node.childs[i]); + } + var j; + for (j in expandedNodes) { + var objName; + objName = this.options.onObjectName({ + path: expandedNodes[j].getPath(), + children: expandedNodes[j].childs + }); + var count = this.childs ? this.childs.length : 0; + expandedNodes[j].dom.value.innerHTML = '{' + (objName || count) + '}'; + } + } + } + catch (err) { + console.error('Error in onObjectName callback: ', err); + } + } + + function getExpandedNodes(node) { + if (typeof node.childs !== 'undefined') { + var a = node.childs + .filter(function(n) { + return n.expanded !== 'undefined' && n.expanded; + }) + .flatMap(function(n) { + return getExpandedNodes(n); + }); + return a.length ? a : [node]; + } else { + return [node]; + } + } }; /** @@ -1711,8 +1752,8 @@ treemode.getSelection = function () { /** * Callback registration for selection change - * @param {selectionCallback} callback - * + * @param {selectionCallback} callback + * * @callback selectionCallback */ treemode.onSelectionChange = function (callback) { @@ -1726,7 +1767,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 +1778,7 @@ treemode.setSelection = function (start, end) { } var nodes = this._getNodeInstancesByRange(start, end); - + nodes.forEach(function(node) { node.expandTo(); }); @@ -1746,7 +1787,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 From f9a372aeef9b08d5e69bf022ceac2ab09261ecaf Mon Sep 17 00:00:00 2001 From: bnanchen Date: Fri, 21 Dec 2018 08:35:57 +0100 Subject: [PATCH 3/7] Creation of node.prototype.updateObjectName method --- src/js/Node.js | 30 ++++++++++++++++++++++-------- src/js/treemode.js | 21 +++++++-------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/js/Node.js b/src/js/Node.js index 151479f29..0ab6241ba 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -2464,14 +2464,7 @@ Node.prototype.updateDom = function (options) { util.addClassName(this.dom.tr, 'jsoneditor-expandable'); } else if (this.type == 'object') { - var objName; - if (typeof this.editor.options.onObjectName === 'function') { - objName = this.editor.options.onObjectName({ - path: this.getPath(), - children: this.childs - }); - } - domValue.innerHTML = '{' + (objName || count) + '}'; + this.updateObjectName(); util.addClassName(this.dom.tr, 'jsoneditor-expandable'); } else { @@ -4471,6 +4464,27 @@ Node.prototype._escapeJSON = function (text) { return escaped; }; +/** + * update the object name according to the callback onObjectName + * @private + */ +Node.prototype.updateObjectName = function () { + try { + var count = this.childs ? this.childs.length : 0; + var objName; + if (typeof this.editor.options.onObjectName === 'function') { + objName = this.editor.options.onObjectName({ + path: this.getPath(), + children: this.childs + }); + } + this.dom.value.innerHTML = '{' + (objName || count) + '}'; + } + catch (err) { + console.error('Error in onObjectName callback: ', err); + } +} + // 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 5af7409eb..d24d2ef7e 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -559,20 +559,13 @@ treemode._onChange = function () { if (this.node.childs[i].expanded) { var expandedNodes = getExpandedNodes(this.node.childs[i]); } - var j; - for (j in expandedNodes) { - var objName; - objName = this.options.onObjectName({ - path: expandedNodes[j].getPath(), - children: expandedNodes[j].childs - }); - var count = this.childs ? this.childs.length : 0; - expandedNodes[j].dom.value.innerHTML = '{' + (objName || count) + '}'; - } + var j; + for (j in expandedNodes) { + expandedNodes[j].updateObjectName(); + } } - } - catch (err) { - console.error('Error in onObjectName callback: ', err); + } catch (err) { + console.error("Error in onObjectName callback: ", err); } } @@ -580,7 +573,7 @@ treemode._onChange = function () { if (typeof node.childs !== 'undefined') { var a = node.childs .filter(function(n) { - return n.expanded !== 'undefined' && n.expanded; + return n.expanded !== 'undefined' && n.expanded; }) .flatMap(function(n) { return getExpandedNodes(n); From 3df06e8bcaa6ef3883b3e87e9336d31617377d1a Mon Sep 17 00:00:00 2001 From: bnanchen Date: Fri, 21 Dec 2018 10:00:34 +0100 Subject: [PATCH 4/7] Implementation of recursivelyUpdateObjectName method --- src/js/Node.js | 34 ++++++++++++++++++++++++++-------- src/js/treemode.js | 27 +-------------------------- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/js/Node.js b/src/js/Node.js index 0ab6241ba..2e69d7fd8 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -4470,21 +4470,39 @@ Node.prototype._escapeJSON = function (text) { */ Node.prototype.updateObjectName = function () { try { - var count = this.childs ? this.childs.length : 0; - var objName; - if (typeof this.editor.options.onObjectName === 'function') { - objName = this.editor.options.onObjectName({ - path: this.getPath(), - children: this.childs - }); + if (this.type === 'object') { + var count = this.childs ? this.childs.length : 0; + var objName; + if (typeof this.editor.options.onObjectName === 'function') { + objName = this.editor.options.onObjectName({ + path: this.getPath(), + children: this.childs + }); + } + this.dom.value.innerHTML = '{' + (objName || count) + '}'; } - this.dom.value.innerHTML = '{' + (objName || count) + '}'; } catch (err) { console.error('Error in onObjectName callback: ', err); } } +/** + * update recursively the object's and its children's name. + * @private + */ +Node.prototype.recursivelyUpdateObjectName = function () { + if (this.expanded) { + this.updateObjectName(); + if (this.childs !== 'undefined') { + var i; + for (i in this.childs) { + this.childs[i].recursivelyUpdateObjectName(); + } + } + } +} + // 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 d24d2ef7e..8325fd49c 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -553,36 +553,11 @@ treemode._onChange = function () { // trigger the onObjectName callback if (this.options.onObjectName && this.node.childs) { try { - var i; - var expandedNodes = []; - for (i in this.node.childs) { - if (this.node.childs[i].expanded) { - var expandedNodes = getExpandedNodes(this.node.childs[i]); - } - var j; - for (j in expandedNodes) { - expandedNodes[j].updateObjectName(); - } - } + this.node.recursivelyUpdateObjectName(); } catch (err) { console.error("Error in onObjectName callback: ", err); } } - - function getExpandedNodes(node) { - if (typeof node.childs !== 'undefined') { - var a = node.childs - .filter(function(n) { - return n.expanded !== 'undefined' && n.expanded; - }) - .flatMap(function(n) { - return getExpandedNodes(n); - }); - return a.length ? a : [node]; - } else { - return [node]; - } - } }; /** From c991b8dfd32c1ff2ae7e5d236e13491f1663847f Mon Sep 17 00:00:00 2001 From: bnanchen Date: Wed, 26 Dec 2018 13:35:40 +0100 Subject: [PATCH 5/7] Callback arguments: path and size --- src/js/Node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/Node.js b/src/js/Node.js index 2e69d7fd8..c1807f592 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -4476,7 +4476,7 @@ Node.prototype.updateObjectName = function () { if (typeof this.editor.options.onObjectName === 'function') { objName = this.editor.options.onObjectName({ path: this.getPath(), - children: this.childs + size: count }); } this.dom.value.innerHTML = '{' + (objName || count) + '}'; From eee6a56ca0fcfffb12173029cfd971c39a93fa86 Mon Sep 17 00:00:00 2001 From: bnanchen Date: Thu, 3 Jan 2019 08:24:48 +0100 Subject: [PATCH 6/7] New callback argument - type: array | object --- src/js/Node.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/js/Node.js b/src/js/Node.js index c1807f592..bd5e0ccd1 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -2458,9 +2458,8 @@ 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.updateObjectName(); util.addClassName(this.dom.tr, 'jsoneditor-expandable'); } else if (this.type == 'object') { @@ -4470,16 +4469,27 @@ Node.prototype._escapeJSON = function (text) { */ Node.prototype.updateObjectName = function () { try { + var count = this.childs ? this.childs.length : 0; if (this.type === 'object') { - var count = this.childs ? this.childs.length : 0; var objName; if (typeof this.editor.options.onObjectName === 'function') { objName = this.editor.options.onObjectName({ path: this.getPath(), - size: count + size: count, + type: 'object' }); } this.dom.value.innerHTML = '{' + (objName || count) + '}'; + } else if (this.type === 'array') { + var arrName; + if (typeof this.editor.options.onObjectName === 'function') { + arrName = this.editor.options.onObjectName({ + path: this.getPath(), + size: count, + type: 'array' + }); + } + this.dom.value.innerHTML = '[' + (arrName || count) + ']'; } } catch (err) { From bbeb3b00e15ca5b6104edda0001321ff1ddd6ff1 Mon Sep 17 00:00:00 2001 From: bnanchen Date: Fri, 4 Jan 2019 08:14:35 +0100 Subject: [PATCH 7/7] Code improvement and callback function renaming: onNodeName --- src/js/JSONEditor.js | 2 +- src/js/Node.js | 46 +++++++++++++++++--------------------------- src/js/treemode.js | 8 ++++---- 3 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/js/JSONEditor.js b/src/js/JSONEditor.js index 673c466ff..572a394de 100644 --- a/src/js/JSONEditor.js +++ b/src/js/JSONEditor.js @@ -162,7 +162,7 @@ JSONEditor.VALID_OPTIONS = [ 'ajv', 'schema', 'schemaRefs','templates', 'ace', 'theme', 'autocomplete', 'onChange', 'onChangeJSON', 'onChangeText', - 'onEditable', 'onError', 'onEvent', 'onModeChange', 'onObjectName', '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 bd5e0ccd1..7212cab4a 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -2459,11 +2459,11 @@ Node.prototype.updateDom = function (options) { var domValue = this.dom.value; if (domValue) { if (this.type == 'array') { - this.updateObjectName(); + this.updateNodeName(); util.addClassName(this.dom.tr, 'jsoneditor-expandable'); } else if (this.type == 'object') { - this.updateObjectName(); + this.updateNodeName(); util.addClassName(this.dom.tr, 'jsoneditor-expandable'); } else { @@ -4464,36 +4464,26 @@ Node.prototype._escapeJSON = function (text) { }; /** - * update the object name according to the callback onObjectName + * update the object name according to the callback onNodeName * @private */ -Node.prototype.updateObjectName = function () { +Node.prototype.updateNodeName = function () { try { var count = this.childs ? this.childs.length : 0; - if (this.type === 'object') { - var objName; - if (typeof this.editor.options.onObjectName === 'function') { - objName = this.editor.options.onObjectName({ - path: this.getPath(), - size: count, - type: 'object' - }); - } - this.dom.value.innerHTML = '{' + (objName || count) + '}'; - } else if (this.type === 'array') { - var arrName; - if (typeof this.editor.options.onObjectName === 'function') { - arrName = this.editor.options.onObjectName({ - path: this.getPath(), - size: count, - type: 'array' - }); - } - this.dom.value.innerHTML = '[' + (arrName || count) + ']'; + 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 onObjectName callback: ', err); + console.error('Error in onNodeName callback: ', err); } } @@ -4501,13 +4491,13 @@ Node.prototype.updateObjectName = function () { * update recursively the object's and its children's name. * @private */ -Node.prototype.recursivelyUpdateObjectName = function () { +Node.prototype.recursivelyUpdateNodeName = function () { if (this.expanded) { - this.updateObjectName(); + this.updateNodeName(); if (this.childs !== 'undefined') { var i; for (i in this.childs) { - this.childs[i].recursivelyUpdateObjectName(); + this.childs[i].recursivelyUpdateNodeName(); } } } diff --git a/src/js/treemode.js b/src/js/treemode.js index 8325fd49c..17a12b0b7 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -550,12 +550,12 @@ treemode._onChange = function () { } } - // trigger the onObjectName callback - if (this.options.onObjectName && this.node.childs) { + // trigger the onNodeName callback + if (this.options.onNodeName && this.node.childs) { try { - this.node.recursivelyUpdateObjectName(); + this.node.recursivelyUpdateNodeName(); } catch (err) { - console.error("Error in onObjectName callback: ", err); + console.error("Error in onNodeName callback: ", err); } } };