diff --git a/HISTORY.md b/HISTORY.md index 248ad2d..391a1cc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,7 +6,9 @@ https://github.com/josdejong/jsoneditor ## not yet released, version 4.2.2 - Replaced the PNG icon images with SVG. Thanks @1j01. -- Fixed #230, #227, and #93: html and unicode characters not escaped. +- Implemented a new option `escapeUnicode`, which will show the hexadecimal + unicode instead of the character itself. (See #93 and #230). +- Fixed #227: html codes like `&` not escaped. - Fixed #149: Memory leak when switching mode from/to `code` mode, web worker of Ace editor wasn't cleaned up. - Fixed #234: Remove dependency on a fork of the `jsonlint` project on github. diff --git a/docs/api.md b/docs/api.md index 8ee76f6..6809372 100644 --- a/docs/api.md +++ b/docs/api.md @@ -24,6 +24,9 @@ Constructs a new JSONEditor. - `{function} error` Set a callback method triggered when an error occurs. Invoked with the error as first argument. The callback is only invoked for errors triggered by a users action. + - `{boolean} escapeUnicode` + If true, unicode characters are escaped and displayed as their code instead + of the character. False by default. - `{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'. - `{String} mode` diff --git a/src/js/JSONEditor.js b/src/js/JSONEditor.js index 75448d9..8d1800c 100644 --- a/src/js/JSONEditor.js +++ b/src/js/JSONEditor.js @@ -22,10 +22,13 @@ var util = require('./util'); * {String} name Field name for the root node. * Only applicable for modes * 'tree', 'view', and 'form' - * {Number} indentation Number of indentation - * spaces. 4 by default. - * Only applicable for - * modes 'text' and 'code' + * {Number} indentation Number of indentation + * spaces. 4 by default. + * Only applicable for + * modes 'text' and 'code' + * {boolean} escapeUnicode If true, unicode + * characters are escaped. + * false by default. * @param {Object | undefined} json JSON object */ function JSONEditor (container, options, json) { diff --git a/src/js/Node.js b/src/js/Node.js index 5102e4b..badfb29 100644 --- a/src/js/Node.js +++ b/src/js/Node.js @@ -2857,16 +2857,25 @@ Node.prototype._stringCast = function(str) { * @private */ Node.prototype._escapeHTML = function (text) { - var htmlEscaped = String(text) - .replace(/&/g, '&') // must be replaced first! - .replace(//g, '>') - .replace(/ /g, '  ') // replace double space with an nbsp and space - .replace(/^ /, ' ') // space at start - .replace(/ $/, ' '); // space at end + if (typeof text !== 'string') { + return String(text); + } + else { + var htmlEscaped = String(text) + .replace(/&/g, '&') // must be replaced first! + .replace(//g, '>') + .replace(/ /g, '  ') // replace double space with an nbsp and space + .replace(/^ /, ' ') // space at start + .replace(/ $/, ' '); // space at end - var json = JSON.stringify(htmlEscaped); - return json.substring(1, json.length - 1); + var json = JSON.stringify(htmlEscaped); + var html = json.substring(1, json.length - 1); + if (this.editor.options.escapeUnicode === true) { + html = util.escapeUnicodeChars(html); + } + return html; + } }; /** diff --git a/src/js/textmode.js b/src/js/textmode.js index beb7753..8485ee9 100644 --- a/src/js/textmode.js +++ b/src/js/textmode.js @@ -15,18 +15,21 @@ var textmode = {}; /** * Create a text editor * @param {Element} container - * @param {Object} [options] Object with options. available options: - * {String} mode Available values: - * "text" (default) - * or "code". - * {Number} indentation Number of indentation - * spaces. 2 by default. - * {function} change Callback method - * triggered on change - * {function} onMode Callback method - * triggered after setMode - * {Object} ace A custom instance of - * Ace editor. + * @param {Object} [options] Object with options. available options: + * {String} mode Available values: + * "text" (default) + * or "code". + * {Number} indentation Number of indentation + * spaces. 2 by default. + * {function} change Callback method + * triggered on change + * {function} onMode Callback method + * triggered after setMode + * {Object} ace A custom instance of + * Ace editor. + * {boolean} escapeUnicode If true, unicode + * characters are escaped. + * false by default. * @private */ textmode.create = function (container, options) { @@ -339,11 +342,18 @@ textmode.getText = function() { * @param {String} jsonText */ textmode.setText = function(jsonText) { + if (this.options.escapeUnicode === true) { + text = util.escapeUnicodeChars(jsonText); + } + else { + text = jsonText; + } + if (this.textarea) { - this.textarea.value = jsonText; + this.textarea.value = text; } if (this.editor) { - this.editor.setValue(jsonText, -1); + this.editor.setValue(text, -1); } }; diff --git a/src/js/treemode.js b/src/js/treemode.js index 353d48b..c58f5ac 100644 --- a/src/js/treemode.js +++ b/src/js/treemode.js @@ -22,6 +22,9 @@ var treemode = {}; * {function} change Callback method, triggered * on change of contents * {String} name Field name for the root node. + * {boolean} escapeUnicode If true, unicode + * characters are escaped. + * false by default. * @private */ treemode.create = function (container, options) { diff --git a/src/js/util.js b/src/js/util.js index bbbfe7e..ff1ad19 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -147,6 +147,21 @@ exports.sanitize = function (jsString) { return chars.join(''); }; +/** + * Escape unicode characters. + * For example input '\u2661' (length 1) will output '\\u2661' (length 5). + * @param {string} text + * @return {string} + */ +exports.escapeUnicodeChars = function (text) { + // see https://www.wikiwand.com/en/UTF-16 + // note: we leave surrogate pairs as two individual chars, + // as JSON doesn't interpret them as a single unicode char. + return text.replace(/[\u007F-\uFFFF]/g, function(c) { + return '\\u'+('0000' + c.charCodeAt(0).toString(16)).slice(-4); + }) +}; + /** * Validate a string containing a JSON object * This method uses JSONLint to validate the String. If JSONLint is not diff --git a/test/test_build.html b/test/test_build.html index b080322..fbead76 100644 --- a/test/test_build.html +++ b/test/test_build.html @@ -1,13 +1,12 @@ - Test JSONEditor - + -