Merge branch 'develop' into feature/enumAsDropDownMenus
This commit is contained in:
commit
d1d9ce6135
|
@ -3,10 +3,15 @@
|
||||||
https://github.com/josdejong/jsoneditor
|
https://github.com/josdejong/jsoneditor
|
||||||
|
|
||||||
|
|
||||||
## not yet released, version 5.2.1
|
## 2016-04-06, version 5.3.0
|
||||||
|
|
||||||
|
- Implemented support for sorting object keys naturally. Thanks @edufelipe.
|
||||||
|
- Sorting object keys or array items via the context menu is now also naturally
|
||||||
|
sorted.
|
||||||
- Fixed #283: improved JSON schema error message in case of no
|
- Fixed #283: improved JSON schema error message in case of no
|
||||||
additionalProperties.
|
additionalProperties.
|
||||||
|
- Fixed #286: Calling `get()` or `getText()` caused the editor to lose focus.
|
||||||
|
A regression introduced in v5.2.0.
|
||||||
|
|
||||||
|
|
||||||
## 2016-03-20, version 5.2.0
|
## 2016-03-20, version 5.2.0
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
* Copyright (c) 2011-2016 Jos de Jong, http://jsoneditoronline.org
|
* Copyright (c) 2011-2016 Jos de Jong, http://jsoneditoronline.org
|
||||||
*
|
*
|
||||||
* @author Jos de Jong, <wjosdejong@gmail.com>
|
* @author Jos de Jong, <wjosdejong@gmail.com>
|
||||||
* @version 5.2.0
|
* @version 5.3.0
|
||||||
* @date 2016-03-20
|
* @date 2016-04-06
|
||||||
*/
|
*/
|
||||||
(function webpackUniversalModuleDefinition(root, factory) {
|
(function webpackUniversalModuleDefinition(root, factory) {
|
||||||
if(typeof exports === 'object' && typeof module === 'object')
|
if(typeof exports === 'object' && typeof module === 'object')
|
||||||
|
@ -124,6 +124,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
* {boolean} escapeUnicode If true, unicode
|
* {boolean} escapeUnicode If true, unicode
|
||||||
* characters are escaped.
|
* characters are escaped.
|
||||||
* false by default.
|
* false by default.
|
||||||
|
* {boolean} sortObjectKeys If true, object keys are
|
||||||
|
* sorted before display.
|
||||||
|
* false by default.
|
||||||
* @param {Object | undefined} json JSON object
|
* @param {Object | undefined} json JSON object
|
||||||
*/
|
*/
|
||||||
function JSONEditor (container, options, json) {
|
function JSONEditor (container, options, json) {
|
||||||
|
@ -162,7 +165,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
'ace', 'theme',
|
'ace', 'theme',
|
||||||
'ajv', 'schema',
|
'ajv', 'schema',
|
||||||
'onChange', 'onEditable', 'onError', 'onModeChange',
|
'onChange', 'onEditable', 'onError', 'onModeChange',
|
||||||
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation'
|
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
||||||
];
|
];
|
||||||
|
|
||||||
Object.keys(options).forEach(function (option) {
|
Object.keys(options).forEach(function (option) {
|
||||||
|
@ -641,7 +644,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
treemode.get = function () {
|
treemode.get = function () {
|
||||||
// remove focus from currently edited node
|
// remove focus from currently edited node
|
||||||
if (this.focusTarget) {
|
if (this.focusTarget) {
|
||||||
this.focusTarget.blur();
|
var node = Node.getNodeFromTarget(this.focusTarget);
|
||||||
|
if (node) {
|
||||||
|
node.blur();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.node) {
|
if (this.node) {
|
||||||
|
@ -1449,8 +1455,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
treemode._findTopLevelNodes = function (start, end) {
|
treemode._findTopLevelNodes = function (start, end) {
|
||||||
var startPath = start.getPath();
|
var startPath = start.getNodePath();
|
||||||
var endPath = end.getPath();
|
var endPath = end.getNodePath();
|
||||||
var i = 0;
|
var i = 0;
|
||||||
while (i < startPath.length && startPath[i] === endPath[i]) {
|
while (i < startPath.length && startPath[i] === endPath[i]) {
|
||||||
i++;
|
i++;
|
||||||
|
@ -1646,7 +1652,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
var ace;
|
var ace;
|
||||||
try {
|
try {
|
||||||
ace = __webpack_require__(11);
|
ace = __webpack_require__(10);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
// failed to load ace, no problem, we will fall back to plain text
|
// failed to load ace, no problem, we will fall back to plain text
|
||||||
|
@ -2137,7 +2143,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
/* 3 */
|
/* 3 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
var jsonlint = __webpack_require__(10);
|
var jsonlint = __webpack_require__(11);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse JSON using the parser built-in in the browser.
|
* Parse JSON using the parser built-in in the browser.
|
||||||
|
@ -2797,7 +2803,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
throw new SyntaxError('Index expected after [');
|
throw new SyntaxError('Index expected after [');
|
||||||
}
|
}
|
||||||
|
|
||||||
prop = JSON.parse(jsonPath.substring(1, end));
|
var value = jsonPath.substring(1, end);
|
||||||
|
prop = value === '*' ? value : JSON.parse(value); // parse string and number
|
||||||
remainder = jsonPath.substr(end + 1);
|
remainder = jsonPath.substr(end + 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2829,6 +2836,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error.keyword === 'additionalProperties') {
|
||||||
|
error.message = 'should NOT have additional property: ' + error.params.additionalProperty;
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4046,6 +4057,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
/* 8 */
|
/* 8 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
var naturalSort = __webpack_require__(14);
|
||||||
var ContextMenu = __webpack_require__(7);
|
var ContextMenu = __webpack_require__(7);
|
||||||
var appendNodeFactory = __webpack_require__(12);
|
var appendNodeFactory = __webpack_require__(12);
|
||||||
var util = __webpack_require__(3);
|
var util = __webpack_require__(3);
|
||||||
|
@ -4102,7 +4114,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
var editable = this.editor.options.onEditable({
|
var editable = this.editor.options.onEditable({
|
||||||
field: this.field,
|
field: this.field,
|
||||||
value: this.value,
|
value: this.value,
|
||||||
path: this.getFieldsPath()
|
path: this.getPath()
|
||||||
});
|
});
|
||||||
|
|
||||||
if (typeof editable === 'boolean') {
|
if (typeof editable === 'boolean') {
|
||||||
|
@ -4121,11 +4133,14 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
* Get the path of this node
|
* Get the path of this node
|
||||||
* @return {String[]} Array containing the path to this node
|
* @return {String[]} Array containing the path to this node
|
||||||
*/
|
*/
|
||||||
Node.prototype.getFieldsPath = function () {
|
Node.prototype.getPath = function () {
|
||||||
var node = this;
|
var node = this;
|
||||||
var path = [];
|
var path = [];
|
||||||
while (node) {
|
while (node) {
|
||||||
var field = node.field != undefined ? node.field : node.index;
|
var field = (!node.parent || node.parent.type != 'array')
|
||||||
|
? node.field
|
||||||
|
: node.index;
|
||||||
|
|
||||||
if (field !== undefined) {
|
if (field !== undefined) {
|
||||||
path.unshift(field);
|
path.unshift(field);
|
||||||
}
|
}
|
||||||
|
@ -4358,21 +4373,16 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.value = '';
|
this.value = '';
|
||||||
|
|
||||||
|
// sort object keys
|
||||||
|
if (this.editor.options.sortObjectKeys === true) {
|
||||||
|
this.sort('asc');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// value
|
// value
|
||||||
this.childs = undefined;
|
this.childs = undefined;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
/* TODO
|
|
||||||
if (typeof(value) == 'string') {
|
|
||||||
var escValue = JSON.stringify(value);
|
|
||||||
this.value = escValue.substring(1, escValue.length - 1);
|
|
||||||
console.log('check', value, this.value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.previousValue = this.value;
|
this.previousValue = this.value;
|
||||||
|
@ -4420,8 +4430,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
* Get path of the root node till the current node
|
* Get path of the root node till the current node
|
||||||
* @return {Node[]} Returns an array with nodes
|
* @return {Node[]} Returns an array with nodes
|
||||||
*/
|
*/
|
||||||
Node.prototype.getPath = function() {
|
Node.prototype.getNodePath = function() {
|
||||||
var path = this.parent ? this.parent.getPath() : [];
|
var path = this.parent ? this.parent.getNodePath() : [];
|
||||||
path.push(this);
|
path.push(this);
|
||||||
return path;
|
return path;
|
||||||
};
|
};
|
||||||
|
@ -6795,41 +6805,41 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort the childs of the node. Only applicable when the node has type 'object'
|
* Sort the child's of the node. Only applicable when the node has type 'object'
|
||||||
* or 'array'.
|
* or 'array'.
|
||||||
* @param {String} direction Sorting direction. Available values: "asc", "desc"
|
* @param {String} direction Sorting direction. Available values: "asc", "desc"
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
Node.prototype._onSort = function (direction) {
|
Node.prototype.sort = function (direction) {
|
||||||
if (this._hasChilds()) {
|
if (!this._hasChilds()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var order = (direction == 'desc') ? -1 : 1;
|
var order = (direction == 'desc') ? -1 : 1;
|
||||||
var prop = (this.type == 'array') ? 'value': 'field';
|
var prop = (this.type == 'array') ? 'value': 'field';
|
||||||
this.hideChilds();
|
this.hideChilds();
|
||||||
|
|
||||||
var oldChilds = this.childs;
|
var oldChilds = this.childs;
|
||||||
var oldSort = this.sort;
|
var oldSortOrder = this.sortOrder;
|
||||||
|
|
||||||
// copy the array (the old one will be kept for an undo action
|
// copy the array (the old one will be kept for an undo action
|
||||||
this.childs = this.childs.concat();
|
this.childs = this.childs.concat();
|
||||||
|
|
||||||
// sort the arrays
|
// sort the arrays
|
||||||
this.childs.sort(function (a, b) {
|
this.childs.sort(function (a, b) {
|
||||||
if (a[prop] > b[prop]) return order;
|
return order * naturalSort(a[prop], b[prop]);
|
||||||
if (a[prop] < b[prop]) return -order;
|
|
||||||
return 0;
|
|
||||||
});
|
});
|
||||||
this.sort = (order == 1) ? 'asc' : 'desc';
|
this.sortOrder = (order == 1) ? 'asc' : 'desc';
|
||||||
|
|
||||||
this.editor._onAction('sort', {
|
this.editor._onAction('sort', {
|
||||||
node: this,
|
node: this,
|
||||||
oldChilds: oldChilds,
|
oldChilds: oldChilds,
|
||||||
oldSort: oldSort,
|
oldSort: oldSortOrder,
|
||||||
newChilds: this.childs,
|
newChilds: this.childs,
|
||||||
newSort: this.sort
|
newSort: this.sortOrder
|
||||||
});
|
});
|
||||||
|
|
||||||
this.showChilds();
|
this.showChilds();
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7139,13 +7149,13 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._hasChilds()) {
|
if (this._hasChilds()) {
|
||||||
var direction = ((this.sort == 'asc') ? 'desc': 'asc');
|
var direction = ((this.sortOrder == 'asc') ? 'desc': 'asc');
|
||||||
items.push({
|
items.push({
|
||||||
text: 'Sort',
|
text: 'Sort',
|
||||||
title: 'Sort the childs of this ' + this.type,
|
title: 'Sort the childs of this ' + this.type,
|
||||||
className: 'jsoneditor-sort-' + direction,
|
className: 'jsoneditor-sort-' + direction,
|
||||||
click: function () {
|
click: function () {
|
||||||
node._onSort(direction);
|
node.sort(direction);
|
||||||
},
|
},
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
|
@ -7153,7 +7163,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
className: 'jsoneditor-sort-asc',
|
className: 'jsoneditor-sort-asc',
|
||||||
title: 'Sort the childs of this ' + this.type + ' in ascending order',
|
title: 'Sort the childs of this ' + this.type + ' in ascending order',
|
||||||
click: function () {
|
click: function () {
|
||||||
node._onSort('asc');
|
node.sort('asc');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -7161,7 +7171,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
className: 'jsoneditor-sort-desc',
|
className: 'jsoneditor-sort-desc',
|
||||||
title: 'Sort the childs of this ' + this.type +' in descending order',
|
title: 'Sort the childs of this ' + this.type +' in descending order',
|
||||||
click: function () {
|
click: function () {
|
||||||
node._onSort('desc');
|
node.sort('desc');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -7559,6 +7569,21 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 10 */
|
/* 10 */
|
||||||
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
// load brace
|
||||||
|
var ace = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"brace\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
|
||||||
|
|
||||||
|
// load required ace modules
|
||||||
|
__webpack_require__(15);
|
||||||
|
__webpack_require__(16);
|
||||||
|
__webpack_require__(13);
|
||||||
|
|
||||||
|
module.exports = ace;
|
||||||
|
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 11 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
/* Jison generated parser */
|
/* Jison generated parser */
|
||||||
|
@ -7980,21 +8005,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
exports.parse = jsonlint.parse.bind(jsonlint);
|
exports.parse = jsonlint.parse.bind(jsonlint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***/ },
|
|
||||||
/* 11 */
|
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
|
||||||
|
|
||||||
// load brace
|
|
||||||
var ace = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"brace\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
|
|
||||||
|
|
||||||
// load required ace modules
|
|
||||||
__webpack_require__(14);
|
|
||||||
__webpack_require__(15);
|
|
||||||
__webpack_require__(13);
|
|
||||||
|
|
||||||
module.exports = ace;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 12 */
|
/* 12 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
@ -8379,6 +8389,57 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 14 */
|
/* 14 */
|
||||||
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license
|
||||||
|
* Author: Jim Palmer (based on chunking idea from Dave Koelle)
|
||||||
|
*/
|
||||||
|
/*jshint unused:false */
|
||||||
|
module.exports = function naturalSort (a, b) {
|
||||||
|
"use strict";
|
||||||
|
var re = /(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi,
|
||||||
|
sre = /(^[ ]*|[ ]*$)/g,
|
||||||
|
dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
|
||||||
|
hre = /^0x[0-9a-f]+$/i,
|
||||||
|
ore = /^0/,
|
||||||
|
i = function(s) { return naturalSort.insensitive && ('' + s).toLowerCase() || '' + s; },
|
||||||
|
// convert all to strings strip whitespace
|
||||||
|
x = i(a).replace(sre, '') || '',
|
||||||
|
y = i(b).replace(sre, '') || '',
|
||||||
|
// chunk/tokenize
|
||||||
|
xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
|
||||||
|
yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
|
||||||
|
// numeric, hex or date detection
|
||||||
|
xD = parseInt(x.match(hre), 16) || (xN.length !== 1 && x.match(dre) && Date.parse(x)),
|
||||||
|
yD = parseInt(y.match(hre), 16) || xD && y.match(dre) && Date.parse(y) || null,
|
||||||
|
oFxNcL, oFyNcL;
|
||||||
|
// first try and sort Hex codes or Dates
|
||||||
|
if (yD) {
|
||||||
|
if ( xD < yD ) { return -1; }
|
||||||
|
else if ( xD > yD ) { return 1; }
|
||||||
|
}
|
||||||
|
// natural sorting through split numeric strings and default strings
|
||||||
|
for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
|
||||||
|
// find floats not starting with '0', string or 0 if not defined (Clint Priest)
|
||||||
|
oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
|
||||||
|
oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
|
||||||
|
// handle numeric vs string comparison - number < string - (Kyle Adams)
|
||||||
|
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { return (isNaN(oFxNcL)) ? 1 : -1; }
|
||||||
|
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
|
||||||
|
else if (typeof oFxNcL !== typeof oFyNcL) {
|
||||||
|
oFxNcL += '';
|
||||||
|
oFyNcL += '';
|
||||||
|
}
|
||||||
|
if (oFxNcL < oFyNcL) { return -1; }
|
||||||
|
if (oFxNcL > oFyNcL) { return 1; }
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***/ },
|
||||||
|
/* 15 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
ace.define("ace/mode/json_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(acequire, exports, module) {
|
ace.define("ace/mode/json_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(acequire, exports, module) {
|
||||||
|
@ -9029,7 +9090,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
};
|
};
|
||||||
|
|
||||||
this.createWorker = function(session) {
|
this.createWorker = function(session) {
|
||||||
var worker = new WorkerClient(["ace"], __webpack_require__(16), "JsonWorker");
|
var worker = new WorkerClient(["ace"], __webpack_require__(17), "JsonWorker");
|
||||||
worker.attachToDocument(session.getDocument());
|
worker.attachToDocument(session.getDocument());
|
||||||
|
|
||||||
worker.on("annotate", function(e) {
|
worker.on("annotate", function(e) {
|
||||||
|
@ -9052,7 +9113,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 15 */
|
/* 16 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
ace.define("ace/ext/searchbox",["require","exports","module","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/keyboard/hash_handler","ace/lib/keys"], function(acequire, exports, module) {
|
ace.define("ace/ext/searchbox",["require","exports","module","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/keyboard/hash_handler","ace/lib/keys"], function(acequire, exports, module) {
|
||||||
|
@ -9473,7 +9534,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
|
|
||||||
|
|
||||||
/***/ },
|
/***/ },
|
||||||
/* 16 */
|
/* 17 */
|
||||||
/***/ function(module, exports, __webpack_require__) {
|
/***/ function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
module.exports.id = 'ace/mode/json_worker';
|
module.exports.id = 'ace/mode/json_worker';
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -68,6 +68,10 @@ Constructs a new JSONEditor.
|
||||||
|
|
||||||
If true, unicode characters are escaped and displayed as their hexadecimal code (like `\u260E`) instead of of the character itself (like `☎`). False by default.
|
If true, unicode characters are escaped and displayed as their hexadecimal code (like `\u260E`) instead of of the character itself (like `☎`). False by default.
|
||||||
|
|
||||||
|
- `{boolean} sortObjectKeys`
|
||||||
|
|
||||||
|
If true, object keys in 'tree', 'view' or 'form' mode list be listed alphabetically instead by their insertion order. Sorting is performed using a natural sort algorithm, which makes it easier to see objects that have string numbers as keys. False by default.
|
||||||
|
|
||||||
- `{boolean} history`
|
- `{boolean} history`
|
||||||
|
|
||||||
Enables history, adds a button Undo and Redo to the menu of the JSONEditor. True by default. Only applicable when `mode` is 'tree' or 'form'.
|
Enables history, adds a button Undo and Redo to the menu of the JSONEditor. True by default. Only applicable when `mode` is 'tree' or 'form'.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "jsoneditor",
|
"name": "jsoneditor",
|
||||||
"version": "5.2.0",
|
"version": "5.3.0",
|
||||||
"main": "./index",
|
"main": "./index",
|
||||||
"description": "A web-based tool to view, edit, format, and validate JSON",
|
"description": "A web-based tool to view, edit, format, and validate JSON",
|
||||||
"tags": [
|
"tags": [
|
||||||
|
@ -24,7 +24,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "3.4.0",
|
"ajv": "3.4.0",
|
||||||
"brace": "0.7.0"
|
"brace": "0.7.0",
|
||||||
|
"javascript-natural-sort": "0.7.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"gulp": "3.9.0",
|
"gulp": "3.9.0",
|
||||||
|
|
|
@ -39,6 +39,9 @@ var util = require('./util');
|
||||||
* {boolean} escapeUnicode If true, unicode
|
* {boolean} escapeUnicode If true, unicode
|
||||||
* characters are escaped.
|
* characters are escaped.
|
||||||
* false by default.
|
* false by default.
|
||||||
|
* {boolean} sortObjectKeys If true, object keys are
|
||||||
|
* sorted before display.
|
||||||
|
* false by default.
|
||||||
* @param {Object | undefined} json JSON object
|
* @param {Object | undefined} json JSON object
|
||||||
*/
|
*/
|
||||||
function JSONEditor (container, options, json) {
|
function JSONEditor (container, options, json) {
|
||||||
|
@ -77,7 +80,7 @@ function JSONEditor (container, options, json) {
|
||||||
'ace', 'theme',
|
'ace', 'theme',
|
||||||
'ajv', 'schema',
|
'ajv', 'schema',
|
||||||
'onChange', 'onEditable', 'onError', 'onModeChange',
|
'onChange', 'onEditable', 'onError', 'onModeChange',
|
||||||
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation'
|
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
||||||
];
|
];
|
||||||
|
|
||||||
Object.keys(options).forEach(function (option) {
|
Object.keys(options).forEach(function (option) {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
var naturalSort = require('javascript-natural-sort');
|
||||||
var ContextMenu = require('./ContextMenu');
|
var ContextMenu = require('./ContextMenu');
|
||||||
var appendNodeFactory = require('./appendNodeFactory');
|
var appendNodeFactory = require('./appendNodeFactory');
|
||||||
var util = require('./util');
|
var util = require('./util');
|
||||||
|
@ -54,7 +55,7 @@ Node.prototype._updateEditability = function () {
|
||||||
var editable = this.editor.options.onEditable({
|
var editable = this.editor.options.onEditable({
|
||||||
field: this.field,
|
field: this.field,
|
||||||
value: this.value,
|
value: this.value,
|
||||||
path: this.getFieldsPath()
|
path: this.getPath()
|
||||||
});
|
});
|
||||||
|
|
||||||
if (typeof editable === 'boolean') {
|
if (typeof editable === 'boolean') {
|
||||||
|
@ -73,11 +74,14 @@ Node.prototype._updateEditability = function () {
|
||||||
* Get the path of this node
|
* Get the path of this node
|
||||||
* @return {String[]} Array containing the path to this node
|
* @return {String[]} Array containing the path to this node
|
||||||
*/
|
*/
|
||||||
Node.prototype.getFieldsPath = function () {
|
Node.prototype.getPath = function () {
|
||||||
var node = this;
|
var node = this;
|
||||||
var path = [];
|
var path = [];
|
||||||
while (node) {
|
while (node) {
|
||||||
var field = node.field != undefined ? node.field : node.index;
|
var field = (!node.parent || node.parent.type != 'array')
|
||||||
|
? node.field
|
||||||
|
: node.index;
|
||||||
|
|
||||||
if (field !== undefined) {
|
if (field !== undefined) {
|
||||||
path.unshift(field);
|
path.unshift(field);
|
||||||
}
|
}
|
||||||
|
@ -310,21 +314,16 @@ Node.prototype.setValue = function(value, type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.value = '';
|
this.value = '';
|
||||||
|
|
||||||
|
// sort object keys
|
||||||
|
if (this.editor.options.sortObjectKeys === true) {
|
||||||
|
this.sort('asc');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// value
|
// value
|
||||||
this.childs = undefined;
|
this.childs = undefined;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
/* TODO
|
|
||||||
if (typeof(value) == 'string') {
|
|
||||||
var escValue = JSON.stringify(value);
|
|
||||||
this.value = escValue.substring(1, escValue.length - 1);
|
|
||||||
console.log('check', value, this.value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.previousValue = this.value;
|
this.previousValue = this.value;
|
||||||
|
@ -372,8 +371,8 @@ Node.prototype.getLevel = function() {
|
||||||
* Get path of the root node till the current node
|
* Get path of the root node till the current node
|
||||||
* @return {Node[]} Returns an array with nodes
|
* @return {Node[]} Returns an array with nodes
|
||||||
*/
|
*/
|
||||||
Node.prototype.getPath = function() {
|
Node.prototype.getNodePath = function() {
|
||||||
var path = this.parent ? this.parent.getPath() : [];
|
var path = this.parent ? this.parent.getNodePath() : [];
|
||||||
path.push(this);
|
path.push(this);
|
||||||
return path;
|
return path;
|
||||||
};
|
};
|
||||||
|
@ -2862,41 +2861,41 @@ Node.prototype._onChangeType = function (newType) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort the childs of the node. Only applicable when the node has type 'object'
|
* Sort the child's of the node. Only applicable when the node has type 'object'
|
||||||
* or 'array'.
|
* or 'array'.
|
||||||
* @param {String} direction Sorting direction. Available values: "asc", "desc"
|
* @param {String} direction Sorting direction. Available values: "asc", "desc"
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
Node.prototype._onSort = function (direction) {
|
Node.prototype.sort = function (direction) {
|
||||||
if (this._hasChilds()) {
|
if (!this._hasChilds()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var order = (direction == 'desc') ? -1 : 1;
|
var order = (direction == 'desc') ? -1 : 1;
|
||||||
var prop = (this.type == 'array') ? 'value': 'field';
|
var prop = (this.type == 'array') ? 'value': 'field';
|
||||||
this.hideChilds();
|
this.hideChilds();
|
||||||
|
|
||||||
var oldChilds = this.childs;
|
var oldChilds = this.childs;
|
||||||
var oldSort = this.sort;
|
var oldSortOrder = this.sortOrder;
|
||||||
|
|
||||||
// copy the array (the old one will be kept for an undo action
|
// copy the array (the old one will be kept for an undo action
|
||||||
this.childs = this.childs.concat();
|
this.childs = this.childs.concat();
|
||||||
|
|
||||||
// sort the arrays
|
// sort the arrays
|
||||||
this.childs.sort(function (a, b) {
|
this.childs.sort(function (a, b) {
|
||||||
if (a[prop] > b[prop]) return order;
|
return order * naturalSort(a[prop], b[prop]);
|
||||||
if (a[prop] < b[prop]) return -order;
|
|
||||||
return 0;
|
|
||||||
});
|
});
|
||||||
this.sort = (order == 1) ? 'asc' : 'desc';
|
this.sortOrder = (order == 1) ? 'asc' : 'desc';
|
||||||
|
|
||||||
this.editor._onAction('sort', {
|
this.editor._onAction('sort', {
|
||||||
node: this,
|
node: this,
|
||||||
oldChilds: oldChilds,
|
oldChilds: oldChilds,
|
||||||
oldSort: oldSort,
|
oldSort: oldSortOrder,
|
||||||
newChilds: this.childs,
|
newChilds: this.childs,
|
||||||
newSort: this.sort
|
newSort: this.sortOrder
|
||||||
});
|
});
|
||||||
|
|
||||||
this.showChilds();
|
this.showChilds();
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3206,13 +3205,13 @@ Node.prototype.showContextMenu = function (anchor, onClose) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._hasChilds()) {
|
if (this._hasChilds()) {
|
||||||
var direction = ((this.sort == 'asc') ? 'desc': 'asc');
|
var direction = ((this.sortOrder == 'asc') ? 'desc': 'asc');
|
||||||
items.push({
|
items.push({
|
||||||
text: 'Sort',
|
text: 'Sort',
|
||||||
title: 'Sort the childs of this ' + this.type,
|
title: 'Sort the childs of this ' + this.type,
|
||||||
className: 'jsoneditor-sort-' + direction,
|
className: 'jsoneditor-sort-' + direction,
|
||||||
click: function () {
|
click: function () {
|
||||||
node._onSort(direction);
|
node.sort(direction);
|
||||||
},
|
},
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
|
@ -3220,7 +3219,7 @@ Node.prototype.showContextMenu = function (anchor, onClose) {
|
||||||
className: 'jsoneditor-sort-asc',
|
className: 'jsoneditor-sort-asc',
|
||||||
title: 'Sort the childs of this ' + this.type + ' in ascending order',
|
title: 'Sort the childs of this ' + this.type + ' in ascending order',
|
||||||
click: function () {
|
click: function () {
|
||||||
node._onSort('asc');
|
node.sort('asc');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -3228,7 +3227,7 @@ Node.prototype.showContextMenu = function (anchor, onClose) {
|
||||||
className: 'jsoneditor-sort-desc',
|
className: 'jsoneditor-sort-desc',
|
||||||
title: 'Sort the childs of this ' + this.type +' in descending order',
|
title: 'Sort the childs of this ' + this.type +' in descending order',
|
||||||
click: function () {
|
click: function () {
|
||||||
node._onSort('desc');
|
node.sort('desc');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -180,7 +180,10 @@ treemode.set = function (json, name) {
|
||||||
treemode.get = function () {
|
treemode.get = function () {
|
||||||
// remove focus from currently edited node
|
// remove focus from currently edited node
|
||||||
if (this.focusTarget) {
|
if (this.focusTarget) {
|
||||||
this.focusTarget.blur();
|
var node = Node.getNodeFromTarget(this.focusTarget);
|
||||||
|
if (node) {
|
||||||
|
node.blur();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.node) {
|
if (this.node) {
|
||||||
|
@ -988,8 +991,8 @@ treemode.select = function (nodes) {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
treemode._findTopLevelNodes = function (start, end) {
|
treemode._findTopLevelNodes = function (start, end) {
|
||||||
var startPath = start.getPath();
|
var startPath = start.getNodePath();
|
||||||
var endPath = end.getPath();
|
var endPath = end.getNodePath();
|
||||||
var i = 0;
|
var i = 0;
|
||||||
while (i < startPath.length && startPath[i] === endPath[i]) {
|
while (i < startPath.length && startPath[i] === endPath[i]) {
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -658,7 +658,8 @@ exports.parsePath = function parsePath(jsonPath) {
|
||||||
throw new SyntaxError('Index expected after [');
|
throw new SyntaxError('Index expected after [');
|
||||||
}
|
}
|
||||||
|
|
||||||
prop = JSON.parse(jsonPath.substring(1, end));
|
var value = jsonPath.substring(1, end);
|
||||||
|
prop = value === '*' ? value : JSON.parse(value); // parse string and number
|
||||||
remainder = jsonPath.substr(end + 1);
|
remainder = jsonPath.substr(end + 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var util = require('../src/js/util');
|
var util = require('../src/js/util');
|
||||||
|
|
||||||
|
// console.log('TEST', util.parsePath('.items[3].name'));
|
||||||
|
// console.log('TEST', util.parsePath('.items[*].name'));
|
||||||
|
|
||||||
describe('util', function () {
|
describe('util', function () {
|
||||||
|
|
||||||
describe('sanitize', function () {
|
describe('sanitize', function () {
|
||||||
|
@ -70,6 +73,7 @@ describe('util', function () {
|
||||||
assert.deepEqual(util.parsePath('.foo[2]'), ['foo', 2]);
|
assert.deepEqual(util.parsePath('.foo[2]'), ['foo', 2]);
|
||||||
assert.deepEqual(util.parsePath('.foo[2].bar'), ['foo', 2, 'bar']);
|
assert.deepEqual(util.parsePath('.foo[2].bar'), ['foo', 2, 'bar']);
|
||||||
assert.deepEqual(util.parsePath('.foo["prop with spaces"]'), ['foo', 'prop with spaces']);
|
assert.deepEqual(util.parsePath('.foo["prop with spaces"]'), ['foo', 'prop with spaces']);
|
||||||
|
assert.deepEqual(util.parsePath('.foo[*].bar'), ['foo', '*', 'bar']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it ('should throw an exception in case of an invalid path', function () {
|
it ('should throw an exception in case of an invalid path', function () {
|
||||||
|
|
Loading…
Reference in New Issue