schema-based-json-editor
Version:
A reactjs and vuejs component of schema based json editor.
963 lines (962 loc) • 28.9 kB
JavaScript
import toNumber from 'lodash.tonumber';
import toInteger from 'lodash.tointeger';
import isObject from 'lodash.isobject';
import isInteger from 'lodash.isinteger';
import { defaultLocale as defaultMarkDownTipLocale } from 'markdown-tip';
import { defaultLocale as defaultFileUploaderLocale } from 'file-uploader-component';
export { toNumber, toInteger };
import { __extends, __decorate, __assign } from 'tslib';
window.__extends = __extends;
window.__decorate = __decorate;
window.__assign = __assign;
/**
* @public
*/
export var themes = {
bootstrap3: {
card: 'well',
row: 'row',
errorRow: 'row has-error',
input: 'form-control',
errorInput: 'form-control',
textarea: 'form-control',
errorTextarea: 'form-control',
checkbox: 'checkbox pull-left',
radiobox: 'radio-inline',
button: 'btn btn-default',
buttonGroup: 'btn-group',
title: 'control-label',
description: 'help-block',
select: 'form-control'
},
bootstrap4: {
card: 'card card-body',
row: '',
errorRow: 'text-danger',
input: 'form-control',
errorInput: 'form-control is-invalid',
textarea: 'form-control',
errorTextarea: 'form-control is-invalid',
checkbox: '',
radiobox: '',
button: 'btn btn-default',
buttonGroup: 'btn-group',
title: 'col-form-label',
description: 'form-text',
select: 'form-control'
},
bootstrap5: {
card: 'card card-body',
row: '',
errorRow: 'text-danger',
input: 'form-control',
errorInput: 'form-control is-invalid',
textarea: 'form-control',
errorTextarea: 'form-control is-invalid',
checkbox: '',
radiobox: '',
button: 'btn btn-default',
buttonGroup: 'btn-group',
title: 'col-form-label',
description: 'form-text',
select: 'form-control'
},
antd3: {
card: 'ant-card ant-card-bordered ant-card-body',
row: 'ant-row',
errorRow: 'ant-row has-error',
input: 'ant-input',
errorInput: 'ant-input',
textarea: 'ant-input',
errorTextarea: 'ant-input',
checkbox: 'ant-checkbox',
radiobox: 'ant-radio',
button: 'ant-btn',
buttonGroup: 'ant-btn-group',
title: 'ant-form-item-label',
description: 'ant-form-explain',
select: 'ant-input'
},
'element-ui2': {
card: 'el-form el-card box-card el-card__body',
row: 'el-form-item',
errorRow: 'el-form-item is-error',
input: 'el-input__inner',
errorInput: 'el-input__inner',
textarea: 'el-textarea__inner',
errorTextarea: 'el-textarea__inner',
button: 'el-button el-button--default el-button--small',
buttonGroup: 'el-button-group',
checkbox: 'el-checkbox',
radiobox: 'el-radio',
title: '',
description: '',
select: 'el-input__inner'
},
iview2: {
card: 'ivu-card ivu-card-body',
row: 'ivu-row',
errorRow: 'ivu-row ivu-form-item-error',
input: 'ivu-input',
errorInput: 'ivu-input',
textarea: 'ivu-input',
errorTextarea: 'ivu-input',
button: 'ivu-btn',
buttonGroup: 'ivu-btn-group ivu-btn-group-small',
checkbox: 'ivu-checkbox',
radiobox: 'ivu-radio',
title: 'ivu-form-item-label',
description: '',
select: 'ivu-input'
},
iview3: {
card: 'ivu-card ivu-card-body',
row: 'ivu-row',
errorRow: 'ivu-row ivu-form-item-error',
input: 'ivu-input',
errorInput: 'ivu-input',
textarea: 'ivu-input',
errorTextarea: 'ivu-input',
button: 'ivu-btn',
buttonGroup: 'ivu-btn-group ivu-btn-group-small',
checkbox: 'ivu-checkbox',
radiobox: 'ivu-radio',
title: 'ivu-form-item-label',
description: '',
select: 'ivu-input'
},
blueprint1: {
card: 'pt-card',
row: '',
errorRow: '',
input: 'pt-input pt-fill',
errorInput: 'pt-input pt-fill',
textarea: 'pt-input pt-fill',
errorTextarea: 'pt-input pt-fill',
button: 'pt-button',
buttonGroup: 'pt-button-group',
checkbox: 'pt-checkbox',
radiobox: 'pt-radio',
title: 'pt-label',
description: 'pt-text-muted',
select: 'pt-input pt-fill'
},
blueprint2: {
card: 'pt-card',
row: '',
errorRow: '',
input: 'pt-input pt-fill',
errorInput: 'pt-input pt-fill',
textarea: 'pt-input pt-fill',
errorTextarea: 'pt-input pt-fill',
button: 'pt-button',
buttonGroup: 'pt-button-group',
checkbox: 'pt-checkbox',
radiobox: 'pt-radio',
title: 'pt-label',
description: 'pt-text-muted',
select: 'pt-input pt-fill'
},
blueprint3: {
card: 'pt3-card',
row: '',
errorRow: '',
input: 'pt3-input pt3-fill',
errorInput: 'pt3-input pt3-fill',
textarea: 'pt3-input pt-fill',
errorTextarea: 'pt3-input pt-fill',
button: 'pt3-button',
buttonGroup: 'pt3-button-group',
checkbox: 'pt3-checkbox',
radiobox: 'pt3-radio',
title: 'pt3-label',
description: 'pt3-text-muted',
select: 'pt3-input pt3-fill'
}
};
/**
* @public
*/
export var defaultTheme = {
card: 'schema-based-json-editor--card',
row: 'schema-based-json-editor--row',
errorRow: 'schema-based-json-editor--error-row',
input: 'schema-based-json-editor--input',
errorInput: 'schema-based-json-editor--error-input',
textarea: 'schema-based-json-editor--textarea',
errorTextarea: 'schema-based-json-editor--error-textarea',
checkbox: 'schema-based-json-editor--checkbox',
radiobox: 'schema-based-json-editor--radiobox',
button: 'schema-based-json-editor--button',
buttonGroup: 'schema-based-json-editor--button-group',
title: 'schema-based-json-editor--title',
description: 'schema-based-json-editor--description',
select: 'schema-based-json-editor--select'
};
for (var themeName in themes) {
for (var key in themes[themeName]) {
themes[themeName][key] += ' ' + defaultTheme[key];
}
}
/**
* @public
*/
export function getTheme(name) {
if (name === undefined) {
return defaultTheme;
}
if (typeof name === 'string') {
return themes[name] || defaultTheme;
}
return name;
}
/**
* @public
*/
export var defaultLocale = {
button: {
collapse: 'Collapse',
expand: 'Expand',
add: 'Add',
delete: 'Delete'
},
error: {
minLength: 'Value must be at least {0} characters long.',
maxLength: 'Value must be at most {0} characters long.',
pattern: "Value doesn't match the pattern {0}.",
minimum: 'Value must be >= {0}.',
maximum: 'Value must be <= {0}.',
largerThan: 'Value must be > {0}.',
smallerThan: 'Value must be < {0}.',
minItems: 'The length of the array must be >= {0}.',
uniqueItems: 'The item in {0} and {1} must not be same.',
multipleOf: 'Value must be multiple value of {0}.',
minProperties: 'Properties count must be >= {0}.',
maxProperties: 'Properties count must be <= {0}.'
},
info: {
notExists: 'not exists',
true: 'true',
false: 'false',
search: 'search'
},
markdownTipLocale: defaultMarkDownTipLocale,
fileUploaderLocale: defaultFileUploaderLocale
};
/**
* @public
*/
export var locales = {};
/**
* @public
*/
export function getLocale(locale) {
return locale || defaultLocale;
}
/**
* @public
*/
export var bootstrap3Icon = {
isText: false,
collapse: 'glyphicon glyphicon-chevron-down',
expand: 'glyphicon glyphicon-chevron-right',
add: 'glyphicon glyphicon-plus',
delete: 'glyphicon glyphicon-remove'
};
/**
* @public
*/
export var icons = {
bootstrap3: bootstrap3Icon,
fontawesome4: {
isText: false,
collapse: 'fa fa-caret-square-o-down',
expand: 'fa fa-caret-square-o-right',
add: 'fa fa-plus',
delete: 'fa fa-times'
},
fontawesome5: {
isText: false,
collapse: 'fas fa-caret-square-down',
expand: 'fas fa-caret-square-right',
add: 'fas fa-plus',
delete: 'fas fa-times'
},
antd3: {
isText: false,
collapse: 'anticon anticon-down',
expand: 'anticon anticon-right',
add: 'anticon anticon-plus',
delete: 'anticon anticon-close'
},
'element-ui2': {
isText: false,
collapse: 'el-icon-arrow-down',
expand: 'el-icon-arrow-right',
add: 'el-icon-plus',
delete: 'el-icon-close'
},
iview2: {
isText: false,
collapse: 'ivu-icon ivu-icon-ios-arrow-down',
expand: 'ivu-icon ivu-icon-ios-arrow-right',
add: 'ivu-icon ivu-icon-ios-plus-empty',
delete: 'ivu-icon ivu-icon-ios-close-empty'
},
iview3: {
isText: false,
collapse: 'ivu-icon ivu-icon-ios-arrow-down',
expand: 'ivu-icon ivu-icon-ios-arrow-back',
add: 'ivu-icon ivu-icon-md-add',
delete: 'ivu-icon ivu-icon-md-close'
},
'bootstrap-icons': {
isText: false,
collapse: 'bi bi-arrows-collapse',
expand: 'bi bi-arrows-expand',
add: 'bi bi-plus',
delete: 'bi bi-trash'
}
};
/**
* @public
*/
export function getIcon(name, locale) {
if (name === undefined) {
return {
isText: true,
collapse: locale.button.collapse,
expand: locale.button.expand,
add: locale.button.add,
delete: locale.button.delete
};
}
if (typeof name === 'string') {
return icons[name] || {
isText: true,
collapse: locale.button.collapse,
expand: locale.button.expand,
add: locale.button.add,
delete: locale.button.delete
};
}
return name;
}
/**
* @public
*/
export function getDefaultValue(required, schema, initialValue) {
if (required === void 0) { required = undefined; }
if (initialValue !== undefined) {
switch (schema.type) {
case 'object':
if (isObject(initialValue)) {
return initialValue;
}
break;
case 'array':
if (Array.isArray(initialValue)) {
return initialValue;
}
break;
case 'number':
case 'integer':
if (typeof initialValue === 'number') {
return initialValue;
}
break;
case 'boolean':
if (typeof initialValue === 'boolean') {
return initialValue;
}
break;
case 'string':
if (typeof initialValue === 'string') {
return initialValue;
}
break;
case undefined:
return initialValue;
case 'null':
default:
if (initialValue === null) {
return initialValue;
}
}
}
if (!required) {
return undefined;
}
if (schema.default !== undefined) {
switch (schema.type) {
case 'object':
if (isObject(schema.default)) {
return schema.default;
}
break;
case 'array':
if (Array.isArray(schema.default)) {
return schema.default;
}
break;
case 'number':
case 'integer':
if (typeof schema.default === 'number') {
return schema.default;
}
break;
case 'boolean':
if (typeof schema.default === 'boolean') {
return schema.default;
}
break;
case 'string':
if (typeof schema.default === 'string') {
return schema.default;
}
break;
case 'null':
default:
if (schema.default === null) {
return schema.default;
}
}
}
switch (schema.type) {
case 'object':
var value = {};
for (var property in schema.properties) {
var propertySchema = schema.properties[property];
value[propertySchema.propertyName || property] = undefined;
}
return value;
case 'array':
return [];
case 'number':
case 'integer':
if (schema.enum !== undefined && schema.enum.length > 0) {
return schema.enum[0];
}
else {
return 0;
}
case 'boolean':
return false;
case 'string':
if (schema.enum !== undefined && schema.enum.length > 0) {
return schema.enum[0];
}
else {
return '';
}
case 'null':
default:
return null;
}
}
/**
* @public
*/
export var buttonGroupStyle = { marginLeft: '10px' };
/**
* @public
*/
export var buttonGroupStyleString = 'margin-left: 10px';
/**
* @public
*/
export function isSame(value1, value2) {
if (typeof value1 === 'string'
|| typeof value1 === 'number'
|| typeof value1 === 'boolean'
|| value1 === null
|| value1 === undefined) {
return value1 === value2;
}
if (typeof value2 === 'string'
|| typeof value2 === 'number'
|| typeof value2 === 'boolean'
|| value2 === null
|| value2 === undefined) {
return false;
}
if (Array.isArray(value1)) {
if (Array.isArray(value2) && value1.length === value2.length) {
for (var i = 0; i < value1.length; i++) {
if (!isSame(value1[i], value2[i])) {
return false;
}
}
return true;
}
return false;
}
if (Array.isArray(value2)
|| Object.keys(value1).length !== Object.keys(value2).length) {
return false;
}
for (var key in value1) {
if (value1.hasOwnProperty(key) && !isSame(value1[key], value2[key])) {
return false;
}
}
return true;
}
/**
* @public
*/
export function switchItem(value, el, sibling) {
var fromIndex = +el.dataset.index;
if (sibling) {
var toIndex = +sibling.dataset.index;
value.splice(toIndex, 0, value[fromIndex]);
if (fromIndex > toIndex) {
value.splice(fromIndex + 1, 1);
}
else {
value.splice(fromIndex, 1);
}
}
else {
value.push(value[fromIndex]);
value.splice(fromIndex, 1);
}
}
/**
* @public
*/
export function getErrorMessageOfArray(value, schema, locale) {
if (value !== undefined) {
if (schema.minItems !== undefined && value.length < schema.minItems) {
return locale.error.minItems.replace('{0}', String(schema.minItems));
}
if (schema.uniqueItems) {
for (var i = 1; i < value.length; i++) {
for (var j = 0; j < i; j++) {
if (isSame(value[i], value[j])) {
return locale.error.uniqueItems.replace('{0}', String(j)).replace('{1}', String(i));
}
}
}
}
}
return '';
}
/**
* @public
*/
export function getErrorMessageOfNumber(value, schema, locale) {
if (value !== undefined) {
if (schema.minimum !== undefined) {
if (schema.exclusiveMinimum) {
if (value <= schema.minimum) {
return locale.error.largerThan.replace('{0}', String(schema.minimum));
}
}
else {
if (value < schema.minimum) {
return locale.error.minimum.replace('{0}', String(schema.minimum));
}
}
}
if (schema.maximum !== undefined) {
if (schema.exclusiveMaximum) {
if (value >= schema.maximum) {
return locale.error.smallerThan.replace('{0}', String(schema.maximum));
}
}
else {
if (value > schema.maximum) {
return locale.error.maximum.replace('{0}', String(schema.maximum));
}
}
}
if (schema.multipleOf && schema.multipleOf > 0 && !isInteger(value / schema.multipleOf)) {
return locale.error.multipleOf.replace('{0}', String(schema.multipleOf));
}
}
return '';
}
/**
* @public
*/
export function getErrorMessageOfString(value, schema, locale) {
if (value !== undefined) {
if (schema.minLength !== undefined
&& value.length < schema.minLength) {
return locale.error.minLength.replace('{0}', String(schema.minLength));
}
if (schema.maxLength !== undefined
&& value.length > schema.maxLength) {
return locale.error.maxLength.replace('{0}', String(schema.maxLength));
}
if (schema.pattern !== undefined
&& !new RegExp(schema.pattern).test(value)) {
return locale.error.pattern.replace('{0}', String(schema.pattern));
}
}
return '';
}
/**
* @public
*/
export function getErrorMessageOfObject(value, schema, locale) {
if (value !== undefined) {
var length_1 = 0;
for (var key in value) {
if (value.hasOwnProperty(key) && value[key] !== undefined) {
length_1++;
}
}
if (schema.minProperties !== undefined
&& length_1 < schema.minProperties) {
return locale.error.minProperties.replace('{0}', String(schema.minProperties));
}
if (schema.maxProperties !== undefined
&& length_1 > schema.maxProperties) {
return locale.error.maxProperties.replace('{0}', String(schema.maxProperties));
}
}
return '';
}
/**
* @public
*/
export function toggleOptional(value, schema, initialValue) {
if (value === undefined) {
return getDefaultValue(true, schema, initialValue);
}
else {
return undefined;
}
}
/**
* @public
*/
export function recordInvalidPropertiesOfObject(invalidProperties, isValid, property) {
var index = invalidProperties.indexOf(property);
if (isValid) {
if (index !== -1) {
invalidProperties.splice(index, 1);
}
}
else {
if (index === -1) {
invalidProperties.push(property);
}
}
}
/**
* @public
*/
export function recordInvalidIndexesOfArray(invalidIndexes, isValid, i) {
var index = invalidIndexes.indexOf(i);
if (isValid) {
if (index !== -1) {
invalidIndexes.splice(index, 1);
}
}
else {
if (index === -1) {
invalidIndexes.push(i);
}
}
}
var imageExtensions = ['.png', '.jpg', '.bmp', '.gif'];
/**
* @public
*/
export function isImageUrl(value) {
if (!value || value.length <= 'https://'.length) {
return false;
}
if (value.substr(0, 'http://'.length) !== 'http://'
&& value.substr(0, 'https://'.length) !== 'https://') {
return false;
}
var extensionName = value.substr(value.length - 4, 4);
return imageExtensions.indexOf(extensionName) !== -1;
}
/**
* @public
*/
export function isBase64Image(value) {
if (!value) {
return false;
}
return value.indexOf("data:image/") === 0
&& value.indexOf(";base64,") !== -1;
}
/**
* @public
*/
export function replaceProtocal(src) {
if (src.indexOf('http://') === 0 && src.indexOf('http://localhost') !== 0) {
return 'https://' + src.substring('http://'.length);
}
return src;
}
/**
* @public
*/
export var imagePreviewStyleString = 'display: block; height: auto; margin: 6px 0; max-width: 100%;';
/**
* @public
*/
export var imagePreviewStyle = {
display: 'block',
height: 'auto',
margin: '6px 0',
maxWidth: '100%'
};
function printInConsole(message) {
console.log(message);
}
/**
* @public
*/
export function initializeMarkdown(markdownit, hljs, forceHttps) {
if (forceHttps === void 0) { forceHttps = undefined; }
if (!markdownit) {
return undefined;
}
var md = markdownit({
linkify: true,
highlight: function (str, lang) {
if (hljs) {
if (lang && hljs.getLanguage(lang)) {
try {
return "<pre><code class=\"hljs " + lang + "\">" + hljs.highlight(lang, str).value + "</code></pre>";
}
catch (error) {
printInConsole(error);
}
}
else {
try {
return "<pre><code class=\"hljs\">" + hljs.highlightAuto(str).value + "</code></pre>";
}
catch (error) {
printInConsole(error);
}
}
}
return "<pre><code class=\"hljs\">" + md.utils.escapeHtml(str) + "</code></pre>";
}
});
md.renderer.rules.image = function (tokens, index, options, env, self) {
var token = tokens[index];
var aIndex = token.attrIndex('src');
if (forceHttps) {
token.attrs[aIndex][1] = replaceProtocal(token.attrs[aIndex][1]);
}
token.attrPush(['style', imagePreviewStyleString]);
return md.renderer.rules.image(tokens, index, options, env, self);
};
var defaultLinkRender;
if (md.renderer.rules.link_open) {
defaultLinkRender = md.renderer.rules.link_open;
}
else {
defaultLinkRender = function (tokens, index, options, env, self) {
return self.renderToken(tokens, index, options);
};
}
md.renderer.rules.link_open = function (tokens, index, options, env, self) {
tokens[index].attrPush(['target', '_blank']);
tokens[index].attrPush(['rel', 'nofollow']);
return defaultLinkRender(tokens, index, options, env, self);
};
return md;
}
/**
* @public
*/
export function findTitle(value, properties) {
if (value) {
for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) {
var _a = properties_1[_i], property = _a.property, schema = _a.schema;
var title = value[property];
if ((schema.type === 'number'
|| schema.type === 'integer'
|| schema.type === 'string')
&& schema.enum && schema.enumTitles) {
var index = schema.enum.indexOf(title);
if (index !== -1 && index < schema.enumTitles.length) {
var enumTitle = schema.enumTitles[index];
if (typeof enumTitle === 'string' && enumTitle.length > 0) {
if (enumTitle.length > 23) {
return enumTitle.substring(0, 20) + '...';
}
return enumTitle;
}
}
}
if (typeof title === 'string' && title.length > 0) {
if (title.length > 23) {
return title.substring(0, 20) + '...';
}
return title;
}
}
}
return undefined;
}
function findTitleFromSchema(value, schema) {
if (value) {
for (var property in schema.properties) {
if (schema.properties.hasOwnProperty(property)) {
var title = value[property];
if (typeof title === 'string' && title.length > 0) {
if (title.length > 23) {
return title.substring(0, 20) + '...';
}
return title;
}
}
}
}
return undefined;
}
/**
* @public
*/
export function getTitle() {
var titles = [];
for (var _i = 0; _i < arguments.length; _i++) {
titles[_i] = arguments[_i];
}
for (var _a = 0, titles_1 = titles; _a < titles_1.length; _a++) {
var title = titles_1[_a];
if (title === undefined || title === null) {
continue;
}
return String(title);
}
return '';
}
/**
* @public
*/
export function compare(a, b) {
if (typeof a.schema.propertyOrder === 'number') {
if (typeof b.schema.propertyOrder === 'number') {
return a.schema.propertyOrder - b.schema.propertyOrder;
}
return -1;
}
if (typeof b.schema.propertyOrder === 'number') {
return 1;
}
return 0;
}
/**
* @public
*/
export function filterObject(_a, filterValue) {
var property = _a.property, schema = _a.schema;
return filterValue === ''
|| property.indexOf(filterValue) !== -1
|| (!!schema.title && schema.title.indexOf(filterValue) !== -1)
|| (!!schema.description && schema.description.indexOf(filterValue) !== -1);
}
/**
* @public
*/
export function filterArray(value, index, schema, filterValue) {
var result = filterValue === ''
|| String(index).indexOf(filterValue) !== -1
|| (schema.type === 'string' && value.indexOf(filterValue) !== -1)
|| ((schema.type === 'number' || schema.type === 'integer') && String(value).indexOf(filterValue) !== -1);
if (result) {
return true;
}
if (schema.type === 'object') {
var title = getTitle(findTitleFromSchema(value, schema), schema.title);
return title.indexOf(filterValue) !== -1;
}
return false;
}
/**
* @public
*/
export var minItemCountIfNeedFilter = 6;
/**
* @public
*/
export function isRequired(required, value, schema, property) {
/**
* return true: required
* return undefined: optional
* return false: hidden
*/
if (required && required.some(function (r) { return r === property; })) {
return true;
}
if (value && schema.properties[property]) {
var requiredWhen = schema.properties[property].requiredWhen;
if (requiredWhen) {
var left = requiredWhen[0], operator = requiredWhen[1];
var right = requiredWhen[2];
if (schema.properties[left]) {
if (operator === '===') {
return value[left] === right;
}
if (operator === 'in') {
return Array.isArray(right) && right.indexOf(value[left]) !== -1;
}
if (operator === 'isUndefined') {
return value[left] === undefined;
}
}
}
var optionalWhen = schema.properties[property].optionalWhen;
if (optionalWhen) {
var left = optionalWhen[0], operator = optionalWhen[1];
var right = optionalWhen[2];
if (schema.properties[left]) {
if (operator === '===') {
return value[left] === right ? undefined : false;
}
if (operator === 'in') {
return Array.isArray(right) && right.indexOf(value[left]) !== -1 ? undefined : false;
}
if (operator === 'isUndefined') {
return value[left] === undefined ? undefined : false;
}
}
}
}
return undefined;
}
/**
* @public
*/
export function findContainer(childNodes) {
for (var i = 0; i < childNodes.length; i++) {
var node = childNodes[i];
if (node.nodeName === 'DIV') {
return node;
}
}
return undefined;
}
/**
* @public
*/
export function getOptions(schema) {
var enumTitles = schema.enumTitles || [];
return schema.enum.map(function (e, i) { return ({
value: e,
label: typeof enumTitles[i] === 'string' ? enumTitles[i] : e
}); });
}
/**
* @public
*/
export function getNumberStep(schema) {
if (schema.step !== undefined) {
return schema.step;
}
return schema.type === 'number' ? 'any' : undefined;
}