@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
141 lines (138 loc) • 4.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.validationErrorHandler = exports.validateADFEntity = exports.UNSUPPORTED_NODE_ATTRIBUTE = void 0;
exports.wrapWithUnsupported = wrapWithUnsupported;
var _validator = require("@atlaskit/adf-utils/validator");
var _analytics = require("../analytics");
var _trackUnsupportedContent = require("./track-unsupported-content");
var UNSUPPORTED_NODE_ATTRIBUTE = exports.UNSUPPORTED_NODE_ATTRIBUTE = 'unsupportedNodeAttribute';
var errorCallbackFor = function errorCallbackFor(marks, validate, dispatchAnalyticsEvent) {
return function (entity, error, options) {
return validationErrorHandler(entity, error, options, marks, validate, dispatchAnalyticsEvent);
};
};
var validationErrorHandler = exports.validationErrorHandler = function validationErrorHandler(entity, error, options, marks, validate, dispatchAnalyticsEvent) {
if (entity && entity.type === UNSUPPORTED_NODE_ATTRIBUTE) {
return entity;
}
if (options.isMark) {
return wrapWithUnsupported(error.meta, 'mark');
}
if (options.isNodeAttribute) {
var entityType = entity && entity.type ? entity.type : undefined;
return {
type: UNSUPPORTED_NODE_ATTRIBUTE,
attrs: {
type: {
nodeType: entityType
},
unsupported: error.meta
}
};
}
if (entity && marks.indexOf(entity.type) > -1) {
return;
}
/**
* There's a inconsistency between ProseMirror and ADF.
* `content` is actually optional in ProseMirror.
* And, also empty `text` node is not valid.
*/
if (error.code === 'MISSING_PROPERTIES' && entity.type === 'paragraph') {
return {
type: 'paragraph',
content: []
};
}
// TODO: We can repair missing content like `panel` without a `paragraph`.
if (error.code === 'INVALID_CONTENT_LENGTH') {
if (error.meta && options.allowUnsupportedBlock && entity.content) {
return getEntityForInvalidContentLength(error, entity, validate, marks, dispatchAnalyticsEvent);
} else {
// Can't fix it by wrapping
if (dispatchAnalyticsEvent) {
trackValidationError(dispatchAnalyticsEvent, error, entity);
}
}
}
if (options.allowUnsupportedBlock) {
return wrapWithUnsupported(entity);
}
if (options.allowUnsupportedInline) {
return wrapWithUnsupported(entity, 'inline');
}
if (dispatchAnalyticsEvent) {
trackValidationError(dispatchAnalyticsEvent, error, entity);
}
return entity;
};
function getEntityForInvalidContentLength(error, entity, validate, marks, dispatchAnalyticsEvent) {
var meta = error.meta;
if (meta.type === 'maximum') {
entity.content = entity.content.filter(function (x) {
return !!x;
}).map(function (child, index) {
return index >= meta.requiredLength && child.type !== 'unsupportedBlock' ? wrapWithUnsupported(child) : validate(child, errorCallbackFor(marks, validate, dispatchAnalyticsEvent)).entity;
});
}
if (meta.type === 'minimum') {
if (entity.content.length === 0) {
return wrapWithUnsupported(entity);
}
entity.content = entity.content.filter(function (x) {
return !!x;
}).map(function (child) {
return child.type !== 'unsupportedBlock' ? wrapWithUnsupported(child) : child;
});
}
return entity;
}
function trackValidationError(dispatchAnalyticsEvent, error, entity) {
if (!dispatchAnalyticsEvent) {
return;
}
(0, _trackUnsupportedContent.fireUnsupportedEvent)(dispatchAnalyticsEvent, _analytics.ACTION_SUBJECT_ID.UNSUPPORTED_ERROR, {
type: entity.type || '',
ancestry: entity.ancestorHierarchy || '',
parentType: entity.parentType || '',
marks: entity.marks || [],
attrs: entity.attrs || {}
}, error.code);
}
var validateADFEntity = exports.validateADFEntity = function validateADFEntity(schema, node, dispatchAnalyticsEvent) {
var nodes = Object.keys(schema.nodes);
var marks = Object.keys(schema.marks);
var validate = (0, _validator.validator)(nodes, marks, {
allowPrivateAttributes: true
});
var emptyDoc = {
type: 'doc',
content: []
};
var _validate = validate(node, errorCallbackFor(marks, validate, dispatchAnalyticsEvent)),
_validate$entity = _validate.entity,
entity = _validate$entity === void 0 ? emptyDoc : _validate$entity;
return entity;
};
function wrapWithUnsupported(originalValue) {
var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'block';
var unsupportedNodeType;
switch (type) {
case 'inline':
unsupportedNodeType = 'unsupportedInline';
break;
case 'mark':
unsupportedNodeType = 'unsupportedMark';
break;
default:
unsupportedNodeType = 'unsupportedBlock';
}
return {
type: unsupportedNodeType,
attrs: {
originalValue: originalValue
}
};
}