Implemented `preview` mode (WIP)
This commit is contained in:
parent
7f5e0c6870
commit
1e1ee3463c
|
@ -280,6 +280,23 @@ div.jsoneditor-outer.has-nav-bar.has-main-menu-bar {
|
||||||
padding-top: 61px;
|
padding-top: 61px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.jsoneditor pre.jsoneditor-preview {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
div.jsoneditor code.jsoneditor-preview {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 2px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
textarea.jsoneditor-text,
|
textarea.jsoneditor-text,
|
||||||
.ace-jsoneditor {
|
.ace-jsoneditor {
|
||||||
min-height: 150px;
|
min-height: 150px;
|
||||||
|
@ -353,16 +370,13 @@ div.jsoneditor-value,
|
||||||
div.jsoneditor td,
|
div.jsoneditor td,
|
||||||
div.jsoneditor th,
|
div.jsoneditor th,
|
||||||
div.jsoneditor textarea,
|
div.jsoneditor textarea,
|
||||||
.jsoneditor-schema-error {
|
div.jsoneditor pre.jsoneditor-preview,
|
||||||
|
div.jsoneditor .jsoneditor-schema-error {
|
||||||
font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif;
|
font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
color: #1A1A1A;
|
color: #1A1A1A;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* popover */
|
/* popover */
|
||||||
.jsoneditor-schema-error {
|
.jsoneditor-schema-error {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
|
|
@ -11,7 +11,8 @@ div.jsoneditor-statusbar {
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.jsoneditor-statusbar > .jsoneditor-curserinfo-label {
|
div.jsoneditor-statusbar > .jsoneditor-curserinfo-label,
|
||||||
|
div.jsoneditor-statusbar > .jsoneditor-size-info {
|
||||||
margin: 0 2px 0 4px;
|
margin: 0 2px 0 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ var VanillaPicker = require('./vanilla-picker'); // may be undefined in case of
|
||||||
|
|
||||||
var treemode = require('./treemode');
|
var treemode = require('./treemode');
|
||||||
var textmode = require('./textmode');
|
var textmode = require('./textmode');
|
||||||
|
var previewmode = require('./previewmode');
|
||||||
var util = require('./util');
|
var util = require('./util');
|
||||||
|
|
||||||
if (typeof Promise === 'undefined') {
|
if (typeof Promise === 'undefined') {
|
||||||
|
@ -472,9 +473,10 @@ JSONEditor.registerMode = function (mode) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// register tree and text modes
|
// register tree, text, and preview modes
|
||||||
JSONEditor.registerMode(treemode);
|
JSONEditor.registerMode(treemode);
|
||||||
JSONEditor.registerMode(textmode);
|
JSONEditor.registerMode(textmode);
|
||||||
|
JSONEditor.registerMode(previewmode);
|
||||||
|
|
||||||
// expose some of the libraries that can be used customized
|
// expose some of the libraries that can be used customized
|
||||||
JSONEditor.ace = ace;
|
JSONEditor.ace = ace;
|
||||||
|
|
|
@ -48,6 +48,13 @@ function ModeSwitcher(container, modes, current, onSwitch) {
|
||||||
'click': function () {
|
'click': function () {
|
||||||
onSwitch('view');
|
onSwitch('view');
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
preview: {
|
||||||
|
'text': translate('modePreviewText'),
|
||||||
|
'title': translate('modePreviewTitle'),
|
||||||
|
'click': function () {
|
||||||
|
onSwitch('preview');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,8 @@ var _defs = {
|
||||||
modeTreeTitle: 'Switch to tree editor',
|
modeTreeTitle: 'Switch to tree editor',
|
||||||
modeViewText: 'View',
|
modeViewText: 'View',
|
||||||
modeViewTitle: 'Switch to tree view',
|
modeViewTitle: 'Switch to tree view',
|
||||||
|
modePreviewText: 'Preview',
|
||||||
|
modePreviewTitle: 'Switch to preview mode',
|
||||||
examples: 'Examples',
|
examples: 'Examples',
|
||||||
default: 'Default',
|
default: 'Default',
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,464 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var jmespath = require('jmespath');
|
||||||
|
var translate = require('./i18n').translate;
|
||||||
|
var ModeSwitcher = require('./ModeSwitcher');
|
||||||
|
var showSortModal = require('./showSortModal');
|
||||||
|
var showTransformModal = require('./showTransformModal');
|
||||||
|
var util = require('./util');
|
||||||
|
|
||||||
|
// create a mixin with the functions for text mode
|
||||||
|
var previewmode = {};
|
||||||
|
|
||||||
|
var DEFAULT_MODAL_ANCHOR = document.body; // TODO: this constant is defined multiple times
|
||||||
|
var MAX_PREVIEW_CHARACTERS = 100000; // should be enough to fill the editor window
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a JSON document preview, suitable for processing of large documents
|
||||||
|
* @param {Element} container
|
||||||
|
* @param {Object} [options] Object with options. available options:
|
||||||
|
* {String} mode Available values: "preview".
|
||||||
|
* {Number} indentation Number of indentation
|
||||||
|
* spaces. 2 by default.
|
||||||
|
* {function} onChange Callback method triggered on change.
|
||||||
|
* Does not pass the changed contents.
|
||||||
|
* {function} onChangeText Callback method, triggered
|
||||||
|
* in modes on change of contents,
|
||||||
|
* passing the changed contents
|
||||||
|
* as stringified JSON.
|
||||||
|
* {function} onModeChange Callback method
|
||||||
|
* triggered after setMode
|
||||||
|
* {boolean} escapeUnicode If true, unicode
|
||||||
|
* characters are escaped.
|
||||||
|
* false by default.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
previewmode.create = function (container, options) {
|
||||||
|
// read options
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
if (typeof options.statusBar === 'undefined') {
|
||||||
|
options.statusBar = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setting default for previewmode
|
||||||
|
options.mainMenuBar = options.mainMenuBar !== false;
|
||||||
|
options.enableSort = options.enableSort !== false;
|
||||||
|
options.enableTransform = options.enableTransform !== false;
|
||||||
|
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
// indentation
|
||||||
|
if (options.indentation) {
|
||||||
|
this.indentation = Number(options.indentation);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.indentation = 2; // number of spaces
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine mode
|
||||||
|
this.mode = 'preview';
|
||||||
|
|
||||||
|
var me = this;
|
||||||
|
this.container = container;
|
||||||
|
this.dom = {};
|
||||||
|
|
||||||
|
this.json = undefined;
|
||||||
|
this.text = '';
|
||||||
|
|
||||||
|
// TODO: JSON Schema support
|
||||||
|
|
||||||
|
// create a debounced validate function
|
||||||
|
this._debouncedValidate = util.debounce(this.validate.bind(this), this.DEBOUNCE_INTERVAL);
|
||||||
|
|
||||||
|
this.width = container.clientWidth;
|
||||||
|
this.height = container.clientHeight;
|
||||||
|
|
||||||
|
this.frame = document.createElement('div');
|
||||||
|
this.frame.className = 'jsoneditor jsoneditor-mode-preview';
|
||||||
|
this.frame.onclick = function (event) {
|
||||||
|
// prevent default submit action when the editor is located inside a form
|
||||||
|
event.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.content = document.createElement('div');
|
||||||
|
this.content.className = 'jsoneditor-outer';
|
||||||
|
|
||||||
|
this.dom.previewContent = document.createElement('pre');
|
||||||
|
this.dom.previewContent.className = 'jsoneditor-preview';
|
||||||
|
this.dom.previewText = document.createTextNode('');
|
||||||
|
this.dom.previewContent.appendChild(this.dom.previewText);
|
||||||
|
this.content.appendChild(this.dom.previewContent);
|
||||||
|
|
||||||
|
if (this.options.mainMenuBar) {
|
||||||
|
util.addClassName(this.content, 'has-main-menu-bar');
|
||||||
|
|
||||||
|
// create menu
|
||||||
|
this.menu = document.createElement('div');
|
||||||
|
this.menu.className = 'jsoneditor-menu';
|
||||||
|
this.frame.appendChild(this.menu);
|
||||||
|
|
||||||
|
// create format button
|
||||||
|
var buttonFormat = document.createElement('button');
|
||||||
|
buttonFormat.type = 'button';
|
||||||
|
buttonFormat.className = 'jsoneditor-format';
|
||||||
|
buttonFormat.title = 'Format JSON data, with proper indentation and line feeds (Ctrl+\\)';
|
||||||
|
this.menu.appendChild(buttonFormat);
|
||||||
|
buttonFormat.onclick = function () {
|
||||||
|
try {
|
||||||
|
me.format();
|
||||||
|
me._onChange();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
me._onError(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// create compact button
|
||||||
|
var buttonCompact = document.createElement('button');
|
||||||
|
buttonCompact.type = 'button';
|
||||||
|
buttonCompact.className = 'jsoneditor-compact';
|
||||||
|
buttonCompact.title = 'Compact JSON data, remove all whitespaces (Ctrl+Shift+\\)';
|
||||||
|
this.menu.appendChild(buttonCompact);
|
||||||
|
buttonCompact.onclick = function () {
|
||||||
|
try {
|
||||||
|
me.compact();
|
||||||
|
me._onChange();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
me._onError(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// create sort button
|
||||||
|
if (this.options.enableSort) {
|
||||||
|
var sort = document.createElement('button');
|
||||||
|
sort.type = 'button';
|
||||||
|
sort.className = 'jsoneditor-sort';
|
||||||
|
sort.title = translate('sortTitleShort');
|
||||||
|
sort.onclick = function () {
|
||||||
|
me._showSortModal();
|
||||||
|
};
|
||||||
|
this.menu.appendChild(sort);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create transform button
|
||||||
|
if (this.options.enableTransform) {
|
||||||
|
var transform = document.createElement('button');
|
||||||
|
transform.type = 'button';
|
||||||
|
transform.title = translate('transformTitleShort');
|
||||||
|
transform.className = 'jsoneditor-transform';
|
||||||
|
transform.onclick = function () {
|
||||||
|
me._showTransformModal();
|
||||||
|
};
|
||||||
|
this.menu.appendChild(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create repair button
|
||||||
|
var buttonRepair = document.createElement('button');
|
||||||
|
buttonRepair.type = 'button';
|
||||||
|
buttonRepair.className = 'jsoneditor-repair';
|
||||||
|
buttonRepair.title = 'Repair JSON: fix quotes and escape characters, remove comments and JSONP notation, turn JavaScript objects into JSON.';
|
||||||
|
this.menu.appendChild(buttonRepair);
|
||||||
|
buttonRepair.onclick = function () {
|
||||||
|
try {
|
||||||
|
me.repair();
|
||||||
|
me._onChange();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
me._onError(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// create mode box
|
||||||
|
if (this.options && this.options.modes && this.options.modes.length) {
|
||||||
|
this.modeSwitcher = new ModeSwitcher(this.menu, this.options.modes, this.options.mode, function onSwitch(mode) {
|
||||||
|
// switch mode and restore focus
|
||||||
|
me.setMode(mode);
|
||||||
|
me.modeSwitcher.focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.frame.appendChild(this.content);
|
||||||
|
this.container.appendChild(this.frame);
|
||||||
|
|
||||||
|
if (options.statusBar) {
|
||||||
|
util.addClassName(this.content, 'has-status-bar');
|
||||||
|
|
||||||
|
var statusBar = document.createElement('div');
|
||||||
|
this.dom.statusBar = statusBar;
|
||||||
|
statusBar.className = 'jsoneditor-statusbar';
|
||||||
|
this.frame.appendChild(statusBar);
|
||||||
|
|
||||||
|
this.dom.sizeInfo = document.createElement('span');
|
||||||
|
this.dom.sizeInfo.className = 'jsoneditor-size-info';
|
||||||
|
this.dom.sizeInfo.innerText = '';
|
||||||
|
|
||||||
|
statusBar.appendChild(this.dom.sizeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderPreview();
|
||||||
|
|
||||||
|
this.setSchema(this.options.schema, this.options.schemaRefs);
|
||||||
|
};
|
||||||
|
|
||||||
|
previewmode.renderPreview = function () {
|
||||||
|
var text = this.getText();
|
||||||
|
|
||||||
|
this.dom.previewText.nodeValue = (text.length > MAX_PREVIEW_CHARACTERS)
|
||||||
|
? (text.slice(0, MAX_PREVIEW_CHARACTERS) + '...')
|
||||||
|
: text;
|
||||||
|
|
||||||
|
this.dom.sizeInfo.innerText = 'Size: ' + util.formatSize(text.length)
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a change:
|
||||||
|
* - Validate JSON schema
|
||||||
|
* - Send a callback to the onChange listener if provided
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
previewmode._onChange = function () {
|
||||||
|
if (this.onChangeDisabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate JSON schema (if configured)
|
||||||
|
this._debouncedValidate();
|
||||||
|
|
||||||
|
// trigger the onChange callback
|
||||||
|
if (this.options.onChange) {
|
||||||
|
try {
|
||||||
|
this.options.onChange();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.error('Error in onChange callback: ', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trigger the onChangeText callback
|
||||||
|
if (this.options.onChangeText) {
|
||||||
|
try {
|
||||||
|
this.options.onChangeText(this.getText());
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.error('Error in onChangeText callback: ', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a sort modal
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
previewmode._showSortModal = function () {
|
||||||
|
var me = this;
|
||||||
|
var container = this.options.modalAnchor || DEFAULT_MODAL_ANCHOR;
|
||||||
|
var json = this.get();
|
||||||
|
|
||||||
|
function onSort (sortedBy) {
|
||||||
|
if (Array.isArray(json)) {
|
||||||
|
var sortedJson = util.sort(json, sortedBy.path, sortedBy.direction);
|
||||||
|
|
||||||
|
me.sortedBy = sortedBy
|
||||||
|
me.set(sortedJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (util.isObject(json)) {
|
||||||
|
var sortedJson = util.sortObjectKeys(json, sortedBy.direction);
|
||||||
|
|
||||||
|
me.sortedBy = sortedBy;
|
||||||
|
me.set(sortedJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showSortModal(container, json, onSort, me.sortedBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a transform modal
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
previewmode._showTransformModal = function () {
|
||||||
|
var me = this;
|
||||||
|
var anchor = this.options.modalAnchor || DEFAULT_MODAL_ANCHOR;
|
||||||
|
var json = this.get();
|
||||||
|
showTransformModal(anchor, json, function (query) {
|
||||||
|
var updatedJson = jmespath.search(json, query);
|
||||||
|
me.set(updatedJson);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the editor. Clean up DOM, event listeners, and web workers.
|
||||||
|
*/
|
||||||
|
previewmode.destroy = function () {
|
||||||
|
if (this.frame && this.container && this.frame.parentNode == this.container) {
|
||||||
|
this.container.removeChild(this.frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.modeSwitcher) {
|
||||||
|
this.modeSwitcher.destroy();
|
||||||
|
this.modeSwitcher = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._debouncedValidate = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compact the code in the text editor
|
||||||
|
*/
|
||||||
|
previewmode.compact = function () {
|
||||||
|
var json = this.get();
|
||||||
|
var text = JSON.stringify(json);
|
||||||
|
this.setText(text);
|
||||||
|
|
||||||
|
// we know that in this case the json is still the same
|
||||||
|
this.json = json;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the code in the text editor
|
||||||
|
*/
|
||||||
|
previewmode.format = function () {
|
||||||
|
var json = this.get();
|
||||||
|
var text = JSON.stringify(json, null, this.indentation);
|
||||||
|
this.setText(text);
|
||||||
|
|
||||||
|
// we know that in this case the json is still the same
|
||||||
|
this.json = json;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repair the code in the text editor
|
||||||
|
*/
|
||||||
|
previewmode.repair = function () {
|
||||||
|
var text = this.getText();
|
||||||
|
var sanitizedText = util.sanitize(text);
|
||||||
|
this.setText(sanitizedText);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set focus to the formatter
|
||||||
|
*/
|
||||||
|
previewmode.focus = function () {
|
||||||
|
// TODO: implement method focus
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set json data in the formatter
|
||||||
|
* @param {*} json
|
||||||
|
*/
|
||||||
|
previewmode.set = function(json) {
|
||||||
|
this.text = undefined;
|
||||||
|
this.json = json;
|
||||||
|
|
||||||
|
this.renderPreview();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update data. Same as calling `set` in text/code mode.
|
||||||
|
* @param {*} json
|
||||||
|
*/
|
||||||
|
previewmode.update = function(json) {
|
||||||
|
this.set(json);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get json data from the formatter
|
||||||
|
* @return {*} json
|
||||||
|
*/
|
||||||
|
previewmode.get = function() {
|
||||||
|
if (this.json === undefined) {
|
||||||
|
var text = this.getText();
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.time('parse') // TODO: cleanup
|
||||||
|
this.json = util.parse(text); // this can throw an error
|
||||||
|
console.timeEnd('parse') // TODO: cleanup
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
// try to sanitize json, replace JavaScript notation with JSON notation
|
||||||
|
text = util.sanitize(text);
|
||||||
|
|
||||||
|
// try to parse again
|
||||||
|
this.json = util.parse(text); // this can throw an error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.json;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the text contents of the editor
|
||||||
|
* @return {String} jsonText
|
||||||
|
*/
|
||||||
|
previewmode.getText = function() {
|
||||||
|
if (this.text === undefined) {
|
||||||
|
console.time('stringify') // TODO: cleanup
|
||||||
|
this.text = JSON.stringify(this.json, null, this.indentation);
|
||||||
|
console.timeEnd('stringify') // TODO: cleanup
|
||||||
|
|
||||||
|
if (this.options.escapeUnicode === true) {
|
||||||
|
console.time('escape') // TODO: cleanup
|
||||||
|
this.text = util.escapeUnicodeChars(this.text);
|
||||||
|
console.timeEnd('escape') // TODO: cleanup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.text;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the text contents of the editor
|
||||||
|
* @param {String} jsonText
|
||||||
|
*/
|
||||||
|
previewmode.setText = function(jsonText) {
|
||||||
|
if (this.options.escapeUnicode === true) {
|
||||||
|
console.time('escape') // TODO: cleanup
|
||||||
|
this.text = util.escapeUnicodeChars(jsonText);
|
||||||
|
console.timeEnd('escape') // TODO: cleanup
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.text = jsonText;
|
||||||
|
}
|
||||||
|
this.json = undefined;
|
||||||
|
|
||||||
|
this.renderPreview();
|
||||||
|
|
||||||
|
// validate JSON schema
|
||||||
|
this._debouncedValidate();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the text contents
|
||||||
|
* @param {string} jsonText
|
||||||
|
*/
|
||||||
|
previewmode.updateText = function(jsonText) {
|
||||||
|
// don't update if there are no changes
|
||||||
|
if (this.getText() === jsonText) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onChangeDisabled = true; // don't fire an onChange event
|
||||||
|
this.setText(jsonText);
|
||||||
|
this.onChangeDisabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate current JSON object against the configured JSON schema
|
||||||
|
* Throws an exception when no JSON schema is configured
|
||||||
|
*/
|
||||||
|
previewmode.validate = function () {
|
||||||
|
// FIXME: implement validate (also support custom validation)
|
||||||
|
};
|
||||||
|
|
||||||
|
// define modes
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
mode: 'preview',
|
||||||
|
mixin: previewmode,
|
||||||
|
data: 'json'
|
||||||
|
}
|
||||||
|
];
|
|
@ -252,14 +252,22 @@ function showTransformModal (container, json, onTransform) {
|
||||||
|
|
||||||
function updatePreview() {
|
function updatePreview() {
|
||||||
try {
|
try {
|
||||||
|
console.time('transform') // TODO: cleanup
|
||||||
var transformed = jmespath.search(value, query.value);
|
var transformed = jmespath.search(value, query.value);
|
||||||
var lines = JSON.stringify(transformed, null, 2).split('\n');
|
console.timeEnd('transform') // TODO: cleanup
|
||||||
|
|
||||||
|
console.time('stringify') // TODO: cleanup
|
||||||
|
var lines = JSON.stringify(transformed, null, 2)
|
||||||
|
console.timeEnd('stringify') // TODO: cleanup
|
||||||
|
|
||||||
|
console.time('split') // TODO: cleanup
|
||||||
|
lines = lines.split('\n'); // FIXME: remove split, it's slow
|
||||||
|
console.timeEnd('split') // TODO: cleanup
|
||||||
|
|
||||||
if (lines.length > MAX_PREVIEW_LINES) {
|
if (lines.length > MAX_PREVIEW_LINES) {
|
||||||
lines = lines.slice(0, MAX_PREVIEW_LINES).concat(['...'])
|
lines = lines.slice(0, MAX_PREVIEW_LINES).concat(['...'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
preview.className = 'jsoneditor-transform-preview';
|
preview.className = 'jsoneditor-transform-preview';
|
||||||
preview.value = lines.join('\n');
|
preview.value = lines.join('\n');
|
||||||
ok.disabled = false;
|
ok.disabled = false;
|
||||||
|
|
|
@ -179,7 +179,6 @@ textmode.create = function (container, options) {
|
||||||
this.menu.appendChild(sort);
|
this.menu.appendChild(sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
// create transform button
|
// create transform button
|
||||||
if (this.options.enableTransform) {
|
if (this.options.enableTransform) {
|
||||||
var transform = document.createElement('button');
|
var transform = document.createElement('button');
|
||||||
|
|
|
@ -6,6 +6,8 @@ var jsonlint = require('./assets/jsonlint/jsonlint');
|
||||||
var jsonMap = require('json-source-map');
|
var jsonMap = require('json-source-map');
|
||||||
var translate = require('./i18n').translate;
|
var translate = require('./i18n').translate;
|
||||||
|
|
||||||
|
var MAX_ITEMS_FIELDS_COLLECTION = 10000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse JSON using the parser built-in in the browser.
|
* Parse JSON using the parser built-in in the browser.
|
||||||
* On exception, the jsonString is validated and a detailed error is thrown.
|
* On exception, the jsonString is validated and a detailed error is thrown.
|
||||||
|
@ -1213,9 +1215,11 @@ exports.getChildPaths = function (json, includeObjects) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(json)) {
|
if (Array.isArray(json)) {
|
||||||
json.forEach(function (item) {
|
var max = Math.min(json.length, MAX_ITEMS_FIELDS_COLLECTION);
|
||||||
|
for (var i = 0; i < max; i++) {
|
||||||
|
var item = json[i];
|
||||||
getObjectChildPaths(item, pathsMap, '', includeObjects);
|
getObjectChildPaths(item, pathsMap, '', includeObjects);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pathsMap[''] = true;
|
pathsMap[''] = true;
|
||||||
|
@ -1296,6 +1300,36 @@ exports.parseString = function(str) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a human readable document size
|
||||||
|
* For example formatSize(7570718) outputs '7.2 MiB'
|
||||||
|
* @param {number} size
|
||||||
|
* @return {string} Returns a human readable size
|
||||||
|
*/
|
||||||
|
exports.formatSize = function (size) {
|
||||||
|
if (size < 900) {
|
||||||
|
return size.toFixed() + ' B';
|
||||||
|
}
|
||||||
|
|
||||||
|
var KiB = size / 1024;
|
||||||
|
if (KiB < 900) {
|
||||||
|
return KiB.toFixed(1) + ' KiB';
|
||||||
|
}
|
||||||
|
|
||||||
|
var MiB = KiB / 1024;
|
||||||
|
if (MiB < 900) {
|
||||||
|
return MiB.toFixed(1) + ' MiB';
|
||||||
|
}
|
||||||
|
|
||||||
|
var GiB = MiB / 1024;
|
||||||
|
if (GiB < 900) {
|
||||||
|
return GiB.toFixed(1) + ' GiB';
|
||||||
|
}
|
||||||
|
|
||||||
|
var TiB = GiB / 1024;
|
||||||
|
return TiB.toFixed(1) + ' TiB';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether a value is an Object
|
* Test whether a value is an Object
|
||||||
* @param {*} value
|
* @param {*} value
|
||||||
|
|
12605
test/largefile.json
12605
test/largefile.json
File diff suppressed because it is too large
Load Diff
|
@ -407,5 +407,16 @@ describe('util', function () {
|
||||||
]), 'b (copy 3)')
|
]), 'b (copy 3)')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should format a document size in a human readable way', function () {
|
||||||
|
assert.strictEqual(util.formatSize(500), '500 B');
|
||||||
|
assert.strictEqual(util.formatSize(900), '0.9 KiB');
|
||||||
|
assert.strictEqual(util.formatSize(77.89 * 1024), '77.9 KiB');
|
||||||
|
assert.strictEqual(util.formatSize(950 * 1024), '0.9 MiB');
|
||||||
|
assert.strictEqual(util.formatSize(7.22 * 1024 * 1024), '7.2 MiB');
|
||||||
|
assert.strictEqual(util.formatSize(955.4 * 1024 * 1024), '0.9 GiB');
|
||||||
|
assert.strictEqual(util.formatSize(22.37 * 1024 * 1024 * 1024), '22.4 GiB');
|
||||||
|
assert.strictEqual(util.formatSize(1024 * 1024 * 1024 * 1024), '1.0 TiB');
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: thoroughly test all util methods
|
// TODO: thoroughly test all util methods
|
||||||
});
|
});
|
Loading…
Reference in New Issue