@atlaskit/renderer
Version:
Renderer component
263 lines (251 loc) • 10.9 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
/* eslint-disable @atlaskit/editor/no-re-export */
// Entry file in package.json
import { defaultSchema } from '@atlaskit/adf-schema/schema-default';
import { nativeEmbedsFallbackTransform, transformContainerNodes, transformMediaLinkMarks, transformNestedTablesIncomingDocument } from '@atlaskit/adf-utils/transforms';
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
import { findAndTrackUnsupportedContentNodes, validateADFEntity } from '@atlaskit/editor-common/utils';
import { getValidDocument } from '@atlaskit/editor-common/validator';
import { fg } from '@atlaskit/platform-feature-flags';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import memoizeOne from 'memoize-one';
import { PLATFORM } from './analytics/events';
import { trackUnsupportedContentLevels } from './analytics/unsupported-content';
import { countNodes } from './ui/Renderer/count-nodes';
var SUPPORTS_HIRES_TIMER_API = !!(typeof window !== 'undefined' && window.performance && performance.now);
var withStopwatch = function withStopwatch(cb) {
var startTime = SUPPORTS_HIRES_TIMER_API ? performance.now() : Date.now();
var output = cb();
var endTime = SUPPORTS_HIRES_TIMER_API ? performance.now() : Date.now();
var time = endTime - startTime;
return {
output: output,
time: time
};
};
var _validation = function _validation(doc, schema, adfStage, useSpecBasedValidator, dispatchAnalyticsEvent, skipValidation, validationOverrides) {
var result;
if (useSpecBasedValidator) {
// link mark on mediaSingle is deprecated, need to move link mark to child media node
// https://product-fabric.atlassian.net/browse/ED-14043
var _transformMediaLinkMa = transformMediaLinkMarks(doc),
transformedAdf = _transformMediaLinkMa.transformedAdf,
isTransformed = _transformMediaLinkMa.isTransformed;
if (isTransformed && dispatchAnalyticsEvent) {
dispatchAnalyticsEvent({
action: ACTION.MEDIA_LINK_TRANSFORMED,
actionSubject: ACTION_SUBJECT.RENDERER,
eventType: EVENT_TYPE.OPERATIONAL
});
}
result = skipValidation ? transformedAdf || doc : validateADFEntity(schema, transformedAdf || doc, dispatchAnalyticsEvent, validationOverrides);
} else {
result = getValidDocument(doc, schema, adfStage);
}
if (!result) {
return result;
}
// ProseMirror always require a child under doc
if (result.type === 'doc' && useSpecBasedValidator) {
if (Array.isArray(result.content) && result.content.length === 0) {
result.content.push({
type: 'paragraph',
content: []
});
}
// Just making sure doc is always valid
if (!result.version) {
result.version = 1;
}
}
// Convert nested-table extensions into nested tables
try {
var _transformNestedTable = transformNestedTablesIncomingDocument(result),
_transformedAdf = _transformNestedTable.transformedAdf,
_isTransformed = _transformNestedTable.isTransformed;
if (_isTransformed) {
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
action: ACTION.NESTED_TABLE_TRANSFORMED,
actionSubject: ACTION_SUBJECT.RENDERER,
eventType: EVENT_TYPE.OPERATIONAL
});
result = _transformedAdf;
}
} catch (e) {
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
action: ACTION.INVALID_PROSEMIRROR_DOCUMENT,
actionSubject: ACTION_SUBJECT.RENDERER,
eventType: EVENT_TYPE.OPERATIONAL,
attributes: {
platform: PLATFORM.WEB,
errorStack: "".concat(e instanceof Error && e.name === 'NodeNestingTransformError' ? 'NodeNestingTransformError - Failed to encode one or more nested tables' : undefined)
}
});
}
// Upgrade panel → panel_c1 where the schema allows it
if (result && expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
try {
var _transformContainerNo = transformContainerNodes(result, schema),
_transformedAdf2 = _transformContainerNo.transformedAdf,
_isTransformed2 = _transformContainerNo.isTransformed;
if (_isTransformed2 && _transformedAdf2) {
// TODO: EDITOR-7175 - Add analytics
result = _transformedAdf2;
}
} catch (e) {
// TODO: EDITOR-7175 - Add analytics
}
}
if (result && !expValEquals('cc-maui-experiment', 'isEnabled', true) && !fg('platform_native_embeds_rollout_non_maui_experience') && fg('platform_editor_native_embeds_fallback_transform')) {
var _nativeEmbedsFallback = nativeEmbedsFallbackTransform(result, schema),
_transformedAdf3 = _nativeEmbedsFallback.transformedAdf,
hasValidTransform = _nativeEmbedsFallback.hasValidTransform;
if (hasValidTransform && _transformedAdf3) {
dispatchAnalyticsEvent === null || dispatchAnalyticsEvent === void 0 || dispatchAnalyticsEvent({
action: ACTION.NATIVE_EMBEDS_TRANSFORMED,
actionSubject: ACTION_SUBJECT.RENDERER,
eventType: EVENT_TYPE.OPERATIONAL
});
result = _transformedAdf3;
}
}
return result;
};
var memoValidation = memoizeOne(_validation, function (newArgs, lastArgs) {
var _newArgs = _slicedToArray(newArgs, 7),
newDoc = _newArgs[0],
newSchema = _newArgs[1],
newADFStage = _newArgs[2],
newUseSpecValidator = _newArgs[3],
/* ignoring dispatchAnalyticsEvent */newSkipValidation = _newArgs[5],
newValidationOverrides = _newArgs[6];
var _lastArgs = _slicedToArray(lastArgs, 7),
oldDoc = _lastArgs[0],
oldSchema = _lastArgs[1],
oldADFStage = _lastArgs[2],
oldUseSpecValidator = _lastArgs[3],
/* ignoring dispatchAnalyticsEvent */oldSkipValidation = _lastArgs[5],
oldValidationOverrides = _lastArgs[6];
return areDocsEqual(newDoc, oldDoc) && newSchema === oldSchema && newADFStage === oldADFStage && newUseSpecValidator === oldUseSpecValidator && newSkipValidation === oldSkipValidation && newValidationOverrides === oldValidationOverrides;
});
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var areDocsEqual = function areDocsEqual(docA, docB) {
if (docA === docB) {
return true;
}
if (typeof docA === 'string' && typeof docB === 'string') {
return docA === docB;
}
// PMNode
if (docA.type && docA.toJSON && docB.type && docB.toJSON) {
return JSON.stringify(docA.toJSON()) === JSON.stringify(docB.toJSON());
}
// Object
return JSON.stringify(docA) === JSON.stringify(docB);
};
var _serializeFragment = function _serializeFragment(serializer, doc) {
return serializer.serializeFragment(doc.content);
};
var memoSerializeFragment = memoizeOne(_serializeFragment, function (newArgs, lastArgs) {
var _newArgs2 = _slicedToArray(newArgs, 2),
newSerializer = _newArgs2[0],
newDoc = _newArgs2[1];
var _lastArgs2 = _slicedToArray(lastArgs, 2),
oldSerializer = _lastArgs2[0],
oldDoc = _lastArgs2[1];
return newSerializer === oldSerializer && areDocsEqual(newDoc, oldDoc);
});
var _createNodeAndCheck = function _createNodeAndCheck(schema, doc, dispatchAnalyticsEvent) {
var pmNode = schema.nodeFromJSON(doc);
try {
pmNode.check();
} catch (err) {
if (dispatchAnalyticsEvent) {
dispatchAnalyticsEvent({
action: ACTION.INVALID_PROSEMIRROR_DOCUMENT,
actionSubject: ACTION_SUBJECT.RENDERER,
attributes: {
platform: PLATFORM.WEB,
errorStack: err instanceof Error ? err.message : String(err)
},
eventType: EVENT_TYPE.OPERATIONAL
});
}
}
return pmNode;
};
var memoCreateNodeAndCheck = memoizeOne(_createNodeAndCheck, function (newArgs, lastArgs) {
// ignore dispatchAnalyticsEvent
var _newArgs3 = _slicedToArray(newArgs, 2),
newSchema = _newArgs3[0],
newDoc = _newArgs3[1];
var _lastArgs3 = _slicedToArray(lastArgs, 2),
oldSchema = _lastArgs3[0],
oldDoc = _lastArgs3[1];
return newSchema === oldSchema && areDocsEqual(newDoc, oldDoc);
});
export var renderDocument = function renderDocument(doc, serializer) {
var schema = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultSchema;
var adfStage = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'final';
var useSpecBasedValidator = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
var rendererId = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'noid';
var dispatchAnalyticsEvent = arguments.length > 6 ? arguments[6] : undefined;
var unsupportedContentLevelsTracking = arguments.length > 7 ? arguments[7] : undefined;
var appearance = arguments.length > 8 ? arguments[8] : undefined;
var includeNodesCountInStats = arguments.length > 9 ? arguments[9] : undefined;
var skipValidation = arguments.length > 10 ? arguments[10] : undefined;
var validationOverrides = arguments.length > 11 ? arguments[11] : undefined;
var stat = {
sanitizeTime: 0
};
if (fg('platform_editor_renderer_rm_usespecbasedvalidator')) {
useSpecBasedValidator = true;
}
var _withStopwatch = withStopwatch(function () {
return memoValidation(doc, schema, adfStage, useSpecBasedValidator, dispatchAnalyticsEvent, skipValidation, validationOverrides);
}),
validDoc = _withStopwatch.output,
sanitizeTime = _withStopwatch.time;
// save sanitize time to stats
stat.sanitizeTime = sanitizeTime;
if (!validDoc) {
return {
stat: stat,
result: null
};
}
var _withStopwatch2 = withStopwatch(function () {
return memoCreateNodeAndCheck(schema, validDoc, dispatchAnalyticsEvent);
}),
node = _withStopwatch2.output,
buildTreeTime = _withStopwatch2.time;
// save build tree time to stats
stat.buildTreeTime = buildTreeTime;
var _withStopwatch3 = withStopwatch(function () {
return memoSerializeFragment(serializer, node);
}),
result = _withStopwatch3.output,
serializeTime = _withStopwatch3.time;
// save serialize tree time to stats
stat.serializeTime = serializeTime;
if (dispatchAnalyticsEvent && useSpecBasedValidator) {
findAndTrackUnsupportedContentNodes(node, schema, dispatchAnalyticsEvent);
if (unsupportedContentLevelsTracking !== null && unsupportedContentLevelsTracking !== void 0 && unsupportedContentLevelsTracking.enabled) {
var documentData = {
doc: validDoc,
appearance: appearance,
rendererId: rendererId
};
trackUnsupportedContentLevels(documentData, unsupportedContentLevelsTracking, dispatchAnalyticsEvent);
}
}
if (includeNodesCountInStats) {
stat.nodesCount = countNodes(doc);
}
return {
result: result,
stat: stat,
pmDoc: node
};
};