@atlaskit/renderer
Version:
Renderer component
824 lines (819 loc) • 37.2 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
var _excluded = ["key"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import React from 'react';
import { MarkType } from '@atlaskit/editor-prosemirror/model';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { Doc, DocWithSelectAllTrap, isTextNode, isTextWrapper, mergeTextNodes, toReact } from './nodes';
import TextWrapperComponent from './nodes/text-wrapper';
import { isNestedHeaderLinksEnabled } from './utils/links';
import { getColumnWidths } from '@atlaskit/editor-common/utils';
import { getMarksByOrder, isSameMark } from '@atlaskit/editor-common/validator';
import { findChildrenByMark, findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
import { fg } from '@atlaskit/platform-feature-flags';
import { getText } from '../utils';
import { isAnnotationMark, toReact as markToReact } from './marks';
import { isCodeMark } from './marks/code';
import { getNestedUnderNodes, insideBlockNode, insideBreakoutExpand, insideBreakoutLayout, insideMultiBodiedExtension, insideTable } from './renderer-node';
import { renderTextSegments } from './utils/render-text-segments';
import { segmentText } from './utils/segment-text';
import { getStandaloneBackgroundColorMarks } from './utils/getStandaloneBackgroundColorMarks';
import { markBlockAsInline } from './utils/markBlockAsInline';
function mergeMarks(marksAndNodes) {
return marksAndNodes.reduce(function (acc, markOrNode) {
var prev = acc.length && acc[acc.length - 1] || null;
if (markOrNode.type instanceof MarkType && prev && prev.type instanceof MarkType && Array.isArray(prev.content) && isSameMark(prev, markOrNode)) {
prev.content = mergeMarks(prev.content.concat(markOrNode.content));
} else {
acc.push(markOrNode);
}
return acc;
}, []);
}
var ReactSerializer = /*#__PURE__*/function () {
function ReactSerializer(init) {
var _this = this;
_classCallCheck(this, ReactSerializer);
_defineProperty(this, "headingIds", []);
/**
* The reason we have this extra array here is because we need to generate the same unique
* heading id for 2 different nodes: headers and expands (check the implementation of
* `getUniqueHeadingId` for more info).
*
* We will eventually need to refactor the current approach to generate unique ids
* for headers under this ticket -> https://product-fabric.atlassian.net/browse/ED-9668
*/
_defineProperty(this, "expandHeadingIds", []);
_defineProperty(this, "allowCopyToClipboard", false);
_defineProperty(this, "allowWrapCodeBlock", false);
_defineProperty(this, "allowPlaceholderText", true);
_defineProperty(this, "allowCustomPanels", false);
_defineProperty(this, "surroundTextNodesWithTextWrapper", false);
_defineProperty(this, "allowAnnotations", false);
_defineProperty(this, "standaloneBackgroundColorMarks", []);
_defineProperty(this, "inlinePositions", new Set());
_defineProperty(this, "serializeFragmentChild", function (node, _ref) {
var index = _ref.index,
parentInfo = _ref.parentInfo;
var pos = _this.startPos;
var currentPath = parentInfo && parentInfo.path || [];
var parentIsIncompleteTask = (node.type.name === 'taskItem' || node.type.name === 'blockTaskItem' && expValEquals('platform_editor_blocktaskitem_node_tenantid', 'isEnabled', true)) && node.attrs.state !== 'DONE' ||
// If blockTaskItem is in the schema, check if the parent of the current node
// is an incomplete task item, because blockTaskItems can have nested nodes
node.type.schema.nodes.blockTaskItem && (parentInfo === null || parentInfo === void 0 ? void 0 : parentInfo.parentIsIncompleteTask) === true && expValEquals('platform_editor_blocktaskitem_node_tenantid', 'isEnabled', true);
var nodeKey = "".concat(node.type.name, "__").concat(_this.startPos);
var serializedContent = _this.serializeFragment(node.content, _this.getNodeProps(node, parentInfo), toReact(node, {
allowSelectAllTrap: _this.allowSelectAllTrap,
allowWindowedCodeBlock: _this.allowWindowedCodeBlock
}, _this.nodeComponents), nodeKey, {
parentIsIncompleteTask: parentIsIncompleteTask,
path: [].concat(_toConsumableArray(currentPath), [node]),
pos: _this.startPos
});
_this.startPos = pos + node.nodeSize;
var marks = node.marks ? _toConsumableArray(node.marks) : [];
var isMedia = node.type.name === 'media';
var shouldSkipBorderMark = function shouldSkipBorderMark(mark) {
return currentPath.some(function (n) {
var _n$type;
return ((_n$type = n.type) === null || _n$type === void 0 ? void 0 : _n$type.name) !== 'mediaSingle';
}) && isMedia && mark.type.name === 'border';
};
var shouldSkipLinkMark = function shouldSkipLinkMark(mark) {
return _this.allowMediaLinking !== true && isMedia && mark.type.name === 'link';
};
return marks.reduceRight(function (content, mark) {
if (shouldSkipLinkMark(mark) || shouldSkipBorderMark(mark)) {
return content;
}
return _this.renderMark(markToReact(mark), _this.withMediaMarkProps(node, mark, _this.getMarkProps(mark, [], node)), "".concat(mark.type.name, "-").concat(index), content);
}, serializedContent);
});
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_defineProperty(this, "withMediaMarkProps", function (node, mark, defaultProps) {
if (mark.type.name === 'link' && node.type.name === 'media') {
return _objectSpread(_objectSpread({}, defaultProps), {}, {
isMediaLink: true
});
}
if (node.type.name === 'mediaInline' && mark.type.name === 'annotation') {
return _objectSpread(_objectSpread({}, defaultProps), {}, {
isMediaInline: true
});
}
return defaultProps;
});
_defineProperty(this, "getUnsupportedContentProps", function (node) {
return {
node: node,
dispatchAnalyticsEvent: _this.fireAnalyticsEvent
};
});
_defineProperty(this, "getAnnotationMarkProps", function (mark, marksParentPath) {
var annotationParentIds = (marksParentPath || []).reduce(function (acc, parent) {
if (isAnnotationMark(parent)) {
return [].concat(_toConsumableArray(acc), [parent.attrs.id]);
}
return acc;
}, []);
return {
id: mark.attrs.id,
annotationType: mark.attrs.annotationType,
annotationParentIds: annotationParentIds,
allowAnnotations: _this.allowAnnotations,
dataAttributes: {
'data-renderer-mark': true
}
};
});
_defineProperty(this, "getMarkProps", function (mark, marksParentPath, node) {
if (isAnnotationMark(mark)) {
return _this.getAnnotationMarkProps(mark, marksParentPath);
}
var _mark$attrs = mark.attrs,
key = _mark$attrs.key,
otherAttrs = _objectWithoutProperties(_mark$attrs, _excluded);
var extraProps = {
isInline: node === null || node === void 0 ? void 0 : node.isInline
};
// currently the only mark which has custom props is the code mark
var markSpecificProps = isCodeMark(mark) ? {
// The appearance being mobile indicates we are in an renderer being
// rendered by mobile bridge in a web view.
// The tooltip is likely to have unexpected behaviour there, with being cut
// off, so we disable it. This is also to keep the behaviour consistent with
// the rendering in the mobile Native Renderer.
codeBidiWarningTooltipEnabled: false
} : {};
// Add deepLinkTarget for link marks
var linkSpecificProps = mark.type.name === 'link' ? {
onSetLinkTarget: _this.onSetLinkTarget
} : {};
var props = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
eventHandlers: _this.eventHandlers,
fireAnalyticsEvent: _this.fireAnalyticsEvent,
markKey: key
}, otherAttrs), extraProps), markSpecificProps), linkSpecificProps), {}, {
dataAttributes: {
'data-renderer-mark': true
}
});
return props;
});
if (editorExperiment('comment_on_bodied_extensions', true)) {
this.initStartPos = init.startPos || 1;
this.startPos = init.startPos || 1;
} else {
this.initStartPos = 1;
this.startPos = 1;
}
this.providers = init.providers;
this.eventHandlers = init.eventHandlers;
this.extensionHandlers = init.extensionHandlers;
this.portal = init.portal;
this.rendererContext = init.objectContext;
this.appearance = init.appearance;
this.contentMode = init.contentMode;
this.disableHeadingIDs = init.disableHeadingIDs;
this.disableActions = init.disableActions;
this.allowHeadingAnchorLinks = init.allowHeadingAnchorLinks;
this.allowCopyToClipboard = init.allowCopyToClipboard;
this.allowWrapCodeBlock = init.allowWrapCodeBlock;
this.allowPlaceholderText = init.allowPlaceholderText;
this.allowCustomPanels = init.allowCustomPanels;
this.allowColumnSorting = init.allowColumnSorting;
this.fireAnalyticsEvent = init.fireAnalyticsEvent;
this.shouldOpenMediaViewer = init.shouldOpenMediaViewer;
this.allowAltTextOnImages = init.allowAltTextOnImages;
this.stickyHeaders = init.stickyHeaders;
this.allowMediaLinking = init.allowMediaLinking;
this.allowAnnotations = Boolean(init.allowAnnotations);
this.surroundTextNodesWithTextWrapper = Boolean(init.surroundTextNodesWithTextWrapper);
this.media = init.media;
this.emojiResourceConfig = init.emojiResourceConfig;
this.smartLinks = init.smartLinks;
this.extensionViewportSizes = init.extensionViewportSizes;
this.getExtensionHeight = init.getExtensionHeight;
this.allowSelectAllTrap = init.allowSelectAllTrap;
this.nodeComponents = init.nodeComponents;
this.allowWindowedCodeBlock = init.allowWindowedCodeBlock;
this.isInsideOfInlineExtension = init.isInsideOfInlineExtension;
this.textHighlighter = init.textHighlighter;
this.allowTableAlignment = init.allowTableAlignment;
this.allowTableResizing = init.allowTableResizing;
this.allowFixedColumnWidthOption = init.allowFixedColumnWidthOption;
this.isPresentational = init.isPresentational;
this.disableTableOverflowShadow = init.disableTableOverflowShadow;
this.onSetLinkTarget = init.onSetLinkTarget;
this.shouldDisplayExtensionAsInline = init.shouldDisplayExtensionAsInline;
}
return _createClass(ReactSerializer, [{
key: "resetState",
value: function resetState() {
this.headingIds = [];
this.expandHeadingIds = [];
this.startPos = this.initStartPos;
}
}, {
key: "getNodeProps",
value: function getNodeProps(node, parentInfo) {
var path = parentInfo ? parentInfo.path : undefined;
switch (node.type.name) {
case 'date':
return this.getDateProps(node, parentInfo, path);
case 'hardBreak':
return this.getHardBreakProps(node, path);
case 'heading':
return this.getHeadingProps(node, path);
case 'media':
return this.getMediaProps(node, path);
case 'emoji':
return this.getEmojiProps(node, path);
case 'extension':
case 'bodiedExtension':
return this.getExtensionProps(node, path);
case 'mediaGroup':
return this.getMediaGroupProps(node);
case 'mediaInline':
return this.getMediaInlineProps(node);
case 'mediaSingle':
return this.getMediaSingleProps(node, path);
case 'table':
return this.getTableProps(node, path);
case 'tableHeader':
case 'tableRow':
return this.getTableChildrenProps(node);
case 'taskItem':
return this.getTaskItemProps(node, path);
case 'embedCard':
return this.getEmbedCardProps(node, path);
case 'blockCard':
return this.getBlockCardProps(node, path);
case 'inlineCard':
return this.getInlineCardProps(node, path);
case 'expand':
return this.getExpandProps(node, path);
case 'nestedExpand':
if (fg('hot-121622_lazy_load_expand_content')) {
return this.getExpandProps(node, path);
}
return this.getProps(node, path);
case 'unsupportedBlock':
case 'unsupportedInline':
return this.getUnsupportedContentProps(node);
case 'codeBlock':
return this.getCodeBlockProps(node);
case 'panel':
return this.getPanelProps(node);
case 'panel_c1':
if (expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
return this.getPanelProps(node);
}
return this.getProps(node, path);
default:
return this.getProps(node, path);
}
}
}, {
key: "serializeFragment",
value: function serializeFragment(fragment) {
var _this2 = this;
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.allowSelectAllTrap ? DocWithSelectAllTrap : Doc;
var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'root-0';
var parentInfo = arguments.length > 4 ? arguments[4] : undefined;
// This makes sure that we reset internal state on re-render.
if (key === 'root-0') {
this.resetState();
}
return this.renderNode(target, props, key, this.getChildNodes(fragment).map(function (node, index) {
if (isTextWrapper(node)) {
return _this2.serializeTextWrapper(node.content, {
index: index,
parentInfo: parentInfo
});
}
return _this2.serializeFragmentChild(node, {
index: index,
parentInfo: parentInfo
});
}));
}
}, {
key: "serializeTextWrapper",
value: function serializeTextWrapper(content, _ref2) {
var _this$standaloneBackg,
_this3 = this;
var parentInfo = _ref2.parentInfo;
var currentPath = parentInfo && parentInfo.path || [];
var nodePosition = parentInfo && parentInfo.pos || 1;
(_this$standaloneBackg = this.standaloneBackgroundColorMarks).push.apply(_this$standaloneBackg, _toConsumableArray(getStandaloneBackgroundColorMarks(content)));
return ReactSerializer.buildMarkStructure(content).map(function (mark, _index) {
return _this3.serializeMark({
mark: mark,
parentNode: {
path: currentPath,
pos: nodePosition
},
parentMark: {
path: [mark]
}
});
});
}
}, {
key: "serializeMark",
value: function serializeMark(_ref3) {
var _this4 = this;
var mark = _ref3.mark,
parentNode = _ref3.parentNode,
parentMark = _ref3.parentMark;
if (!isTextNode(mark)) {
var serializeContent = function serializeContent(childMark, _index) {
return _this4.serializeMark({
mark: childMark,
parentNode: parentNode,
parentMark: {
path: [].concat(_toConsumableArray(parentMark.path), [childMark])
}
});
};
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var content = (mark.content || []).map(serializeContent);
var markKey = "".concat(mark.type.name, "-component__").concat(this.startPos, "__").concat(parentMark.path.length);
var isStandalone = this.standaloneBackgroundColorMarks.some(function (m) {
return mark.eq(m);
});
return this.renderMark(markToReact(mark), _objectSpread(_objectSpread({}, this.getMarkProps(mark, parentMark.path)), {}, {
isStandalone: isStandalone
}), markKey, content);
}
var startPos = this.startPos;
var endPos = startPos + mark.nodeSize;
this.startPos = endPos;
var textKey = "text-wrapper_".concat(this.startPos);
if (this.surroundTextNodesWithTextWrapper) {
var parentDepth = Math.max(parentNode.path.length - 1, 0);
return /*#__PURE__*/React.createElement(TextWrapperComponent, {
key: textKey,
startPos: startPos + parentDepth,
endPos: endPos + parentDepth,
textHighlighter: this.textHighlighter,
marks: mark.marks
}, mark.text);
}
var segments = segmentText(mark.text, this.textHighlighter);
return renderTextSegments(segments, this.textHighlighter, mark.marks, startPos);
}
}, {
key: "renderNode",
value: function renderNode(
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
NodeComponent,
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
props, key,
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
content) {
return (
/*#__PURE__*/
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
React.createElement(NodeComponent, _extends({
key: key
}, props), content)
);
}
}, {
key: "renderMark",
value: function renderMark(
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
MarkComponent, props, key,
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
content) {
return (
/*#__PURE__*/
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
React.createElement(MarkComponent, _extends({
key: key
}, props), content)
);
}
}, {
key: "getTableChildrenProps",
value: function getTableChildrenProps(node) {
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
allowColumnSorting: this.allowColumnSorting
});
}
}, {
key: "getTableProps",
value: function getTableProps(node) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var isInsideOfBlockNode = insideBlockNode(path, node.type.schema);
var isInsideMultiBodiedExtension = insideMultiBodiedExtension(path, node.type.schema);
var isInsideOfTable = insideTable(path, node.type.schema);
var isStickySafeCenteringEnabled = expValEquals('platform_editor_flex_based_centering', 'isEnabled', true);
var isInsideBreakoutExpand = !isStickySafeCenteringEnabled && expValEquals('platform_editor_table_sticky_header_improvements', 'cohort', 'test_with_overflow') && expValEquals('platform_editor_table_sticky_header_patch_11', 'isEnabled', true) && insideBreakoutExpand(path);
var stickyHeaders = isStickySafeCenteringEnabled ? !isInsideOfTable ? this.stickyHeaders : undefined : !isInsideOfTable && !insideBreakoutLayout(path) && !isInsideBreakoutExpand ? this.stickyHeaders : undefined;
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
allowColumnSorting: this.allowColumnSorting,
columnWidths: getColumnWidths(node),
tableNode: node,
stickyHeaders: stickyHeaders,
isInsideOfBlockNode: isInsideOfBlockNode,
isInsideOfTable: isInsideOfTable,
isInsideMultiBodiedExtension: isInsideMultiBodiedExtension,
allowTableAlignment: this.allowTableAlignment,
allowTableResizing: this.allowTableResizing,
// eslint-disable-next-line @atlaskit/platform/valid-gate-name
isPresentational: fg('platform_renderer_isPresentational') ? this.isPresentational : false,
disableTableOverflowShadow: this.disableTableOverflowShadow,
allowFixedColumnWidthOption: this.allowFixedColumnWidthOption
});
}
}, {
key: "getDateProps",
value: function getDateProps(node, parentInfo) {
var path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
return {
timestamp: node.attrs && node.attrs.timestamp,
parentIsIncompleteTask: parentInfo && parentInfo.parentIsIncompleteTask,
dataAttributes: {
// We need to account for depth (path.length gives up depth) here
// but depth doesnt increment the pos, only accounted for.
'data-renderer-start-pos': this.startPos + path.length
}
};
}
}, {
key: "getMediaSingleProps",
value: function getMediaSingleProps(node) {
var _this5 = this;
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var link = node.type.schema.marks.link;
var isInsideOfBlockNode = insideBlockNode(path, node.type.schema);
var isLinkMark = function isLinkMark(mark) {
return mark.type === link;
};
var childHasLink = node.firstChild && node.firstChild.marks.filter(function (m) {
return isLinkMark(m) || _this5.allowMediaLinking === true;
}).length;
return _objectSpread(_objectSpread({}, this.getProps(node, path)), {}, {
isInsideOfBlockNode: isInsideOfBlockNode,
childHasLink: childHasLink,
allowCaptions: this.media && this.media.allowCaptions,
featureFlags: this.media && this.media.featureFlags
});
}
}, {
key: "getMediaProps",
value: function getMediaProps(node) {
var _this6 = this,
_this$media,
_this$media2,
_this$media3;
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var _node$type$schema$mar = node.type.schema.marks,
annotation = _node$type$schema$mar.annotation,
link = _node$type$schema$mar.link,
border = _node$type$schema$mar.border;
var isChildOfMediaSingle = path.some(function (n) {
var _n$type2;
return ((_n$type2 = n.type) === null || _n$type2 === void 0 ? void 0 : _n$type2.name) === 'mediaSingle';
});
// Only check path for bodiedSyncBlock; syncBlock uses RendererContext
var nestedUnder = editorExperiment('platform_synced_block', true) ? getNestedUnderNodes(path, ['bodiedSyncBlock']) : undefined;
var isAnnotationMark = function isAnnotationMark(mark) {
return mark.type === annotation;
};
var isLinkMark = function isLinkMark(mark) {
return mark.type === link;
};
var isBorderMark = function isBorderMark(mark) {
return isChildOfMediaSingle && mark.type === border;
};
return _objectSpread(_objectSpread({}, this.getProps(node, path)), {}, {
marks: node.marks.filter(function (m) {
return !isLinkMark(m) || _this6.allowMediaLinking === true;
}),
isLinkMark: isLinkMark,
isBorderMark: isBorderMark,
isAnnotationMark: isAnnotationMark,
allowAltTextOnImages: this.allowAltTextOnImages,
featureFlags: this.media && this.media.featureFlags,
shouldOpenMediaViewer: this.shouldOpenMediaViewer,
ssr: (_this$media = this.media) === null || _this$media === void 0 ? void 0 : _this$media.ssr,
// surroundTextNodesWithTextWrapper checks inlineComment.allowDraftMode
allowAnnotationsDraftMode: this.surroundTextNodesWithTextWrapper,
enableSyncMediaCard: (_this$media2 = this.media) === null || _this$media2 === void 0 ? void 0 : _this$media2.enableSyncMediaCard,
mediaViewerExtensions: (_this$media3 = this.media) === null || _this$media3 === void 0 ? void 0 : _this$media3.mediaViewerExtensions,
nestedUnder: nestedUnder
});
}
}, {
key: "getExtensionProps",
value: function getExtensionProps(node) {
var _this$getExtensionHei;
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
return _objectSpread(_objectSpread({}, this.getProps(node, path)), {}, {
extensionViewportSizes: this.extensionViewportSizes,
nodeHeight: (_this$getExtensionHei = this.getExtensionHeight) === null || _this$getExtensionHei === void 0 ? void 0 : _this$getExtensionHei.call(this, node),
shouldDisplayExtensionAsInline: this.shouldDisplayExtensionAsInline
});
}
}, {
key: "getEmojiProps",
value: function getEmojiProps(node) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
return _objectSpread(_objectSpread({}, this.getProps(node, path)), {}, {
resourceConfig: this.emojiResourceConfig
});
}
}, {
key: "getEmbedCardProps",
value: function getEmbedCardProps(node) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var isInsideOfBlockNode = insideBlockNode(path, node.type.schema);
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
isInsideOfBlockNode: isInsideOfBlockNode,
onSetLinkTarget: this.onSetLinkTarget
});
}
}, {
key: "getBlockCardProps",
value: function getBlockCardProps(node) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
isNodeNested: path.length > 0,
onSetLinkTarget: this.onSetLinkTarget
});
}
}, {
key: "getInlineCardProps",
value: function getInlineCardProps(node) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
return _objectSpread(_objectSpread({}, this.getProps(node, path)), {}, {
onSetLinkTarget: this.onSetLinkTarget
});
}
}, {
key: "getMediaGroupProps",
value: function getMediaGroupProps(node) {
var _this$media4, _this$media5;
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
shouldOpenMediaViewer: this.shouldOpenMediaViewer,
allowAltTextOnImages: this.allowAltTextOnImages,
featureFlags: this.media && this.media.featureFlags,
enableDownloadButton: (_this$media4 = this.media) === null || _this$media4 === void 0 ? void 0 : _this$media4.enableDownloadButton,
ssr: (_this$media5 = this.media) === null || _this$media5 === void 0 ? void 0 : _this$media5.ssr
});
}
}, {
key: "getMediaInlineProps",
value: function getMediaInlineProps(node) {
var _this$media6, _this$media7;
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
ssr: (_this$media6 = this.media) === null || _this$media6 === void 0 ? void 0 : _this$media6.ssr,
fallbackMediaNameFetcher: (_this$media7 = this.media) === null || _this$media7 === void 0 ? void 0 : _this$media7.fallbackMediaNameFetcher
});
}
}, {
key: "getTaskItemProps",
value: function getTaskItemProps(node) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
return _objectSpread(_objectSpread({}, this.getProps(node, path)), {}, {
disabled: this.disableActions
});
}
}, {
key: "getHardBreakProps",
value: function getHardBreakProps(node) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var forceNewLine = false;
var parentNode = path.length > 0 ? path[path.length - 1] : null;
if (parentNode && parentNode.lastChild === node) {
forceNewLine = true;
}
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
forceNewLine: forceNewLine
});
}
}, {
key: "getCodeBlockProps",
value: function getCodeBlockProps(node) {
// The appearance being mobile indicates we are in an renderer being
// rendered by mobile bridge in a web view.
// The tooltip is likely to have unexpected behaviour there, with being cut
// off, so we disable it. This is also to keep the behaviour consistent with
// the rendering in the mobile Native Renderer.
var codeBidiWarningTooltipEnabled = false;
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
text: node.textContent,
codeBidiWarningTooltipEnabled: codeBidiWarningTooltipEnabled
});
}
}, {
key: "getPanelProps",
value: function getPanelProps(node) {
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
allowCustomPanels: this.allowCustomPanels
});
}
}, {
key: "getProps",
value: function getProps(node) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var startPos = this.startPos + path.length;
return _objectSpread({
asInline: this.inlinePositions.has(startPos) ? 'on' : undefined,
text: node.text,
providers: this.providers,
eventHandlers: this.eventHandlers,
extensionHandlers: this.extensionHandlers,
portal: this.portal,
rendererContext: this.rendererContext,
serializer: this,
content: node.content ? node.content.toJSON() : undefined,
allowHeadingAnchorLinks: this.allowHeadingAnchorLinks,
allowCopyToClipboard: this.allowCopyToClipboard,
allowWrapCodeBlock: this.allowWrapCodeBlock,
allowPlaceholderText: this.allowPlaceholderText,
rendererAppearance: this.appearance,
rendererContentMode: this.contentMode,
fireAnalyticsEvent: this.fireAnalyticsEvent,
nodeType: node.type.name,
marks: node.marks,
smartLinks: this.smartLinks,
isInsideOfInlineExtension: this.isInsideOfInlineExtension,
dataAttributes: {
// We need to account for depth (path.length gives up depth) here
// but depth doesnt increment the pos, only accounted for.
'data-renderer-start-pos': startPos
},
startPos: startPos,
path: path
}, node.attrs);
}
}, {
key: "headingAnchorSupported",
value: function headingAnchorSupported() {
var path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var isImmediateParent = function isImmediateParent(path, nodeName) {
return path.length > 0 && path[path.length - 1].type.name === nodeName;
};
return isNestedHeaderLinksEnabled(this.allowHeadingAnchorLinks) || path.length === 0 || isImmediateParent(path, 'layoutColumn');
}
}, {
key: "getHeadingProps",
value: function getHeadingProps(node) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
return _objectSpread(_objectSpread({}, this.getProps(node, path)), {}, {
content: node.content ? node.content.toJSON() : undefined,
headingId: this.getHeadingId(node, this.headingIds),
showAnchorLink: this.appearance !== 'comment' && this.allowHeadingAnchorLinks && !this.disableHeadingIDs && this.headingAnchorSupported(path)
});
}
}, {
key: "getExpandProps",
value: function getExpandProps(node) {
var _this7 = this;
var _path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var loadBodyContent = false;
if (fg('hot-121622_lazy_load_expand_content')) {
var annotations = findChildrenByMark(node, node.type.schema.marks.annotation, true);
// Force rendering children if there are inline comments to support comments navigation
// which relies on the HTML node to be present.
loadBodyContent = annotations.some(function (annotation) {
return annotation.node.marks.some(function (mark) {
return mark.attrs.annotationType === 'inlineComment';
});
});
}
if (!isNestedHeaderLinksEnabled(this.allowHeadingAnchorLinks)) {
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
loadBodyContent: loadBodyContent
});
}
var nestedHeaderIds = findChildrenByType(node, node.type.schema.nodes.heading).map(function (_ref4) {
var node = _ref4.node;
return _this7.getHeadingId(node, _this7.expandHeadingIds);
});
return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
nestedHeaderIds: nestedHeaderIds,
loadBodyContent: loadBodyContent
});
}
// The return value of this function is NOT url encoded,
// In HTML5 standard, id can contain any characters, encoding is no necessary.
// Plus we trying to avoid double encoding, therefore we leave the value as is.
// Remember to use encodeURIComponent when generating url from the id value.
}, {
key: "getHeadingId",
value: function getHeadingId(node, headingIds) {
if (this.disableHeadingIDs || !node.content.size) {
return;
}
// We are not use node.textContent here, because we would like to handle cases where
// headings only contain inline blocks like emoji, status and date.
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var nodeContent = node.content.toJSON()
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.reduce(function (acc, node) {
return acc.concat(getText(node) || '');
}, '').trim()
// Ignored via go/ees005
// eslint-disable-next-line require-unicode-regexp
.replace(/\s/g, '-');
if (!nodeContent) {
return;
}
return this.getUniqueHeadingId(nodeContent, headingIds);
}
}, {
key: "getUniqueHeadingId",
value: function getUniqueHeadingId(baseId, headingIds) {
var counter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
if (counter === 0 && headingIds.indexOf(baseId) === -1) {
headingIds.push(baseId);
return baseId;
} else if (counter !== 0) {
var headingId = "".concat(baseId, ".").concat(counter);
if (headingIds.indexOf(headingId) === -1) {
headingIds.push(headingId);
return headingId;
}
}
return this.getUniqueHeadingId(baseId, headingIds, ++counter);
}
}, {
key: "getChildNodes",
value: function getChildNodes(fragment) {
var _this8 = this;
var children = [];
fragment.forEach(function (node) {
children.push(node);
});
children = mergeTextNodes(children);
if (!!this.shouldDisplayExtensionAsInline && expValEquals('platform_editor_render_bodied_extension_as_inline', 'isEnabled', true)) {
markBlockAsInline({
nodes: children,
onMark: function onMark(_ref5) {
var pos = _ref5.pos;
_this8.inlinePositions.add(pos);
},
parentPos: this.startPos,
shouldDisplayExtensionAsInline: this.shouldDisplayExtensionAsInline
});
}
return children;
}
}], [{
key: "getMarks",
value: function getMarks(node) {
if (!node.marks || node.marks.length === 0) {
return [];
}
return getMarksByOrder(node.marks);
}
}, {
key: "buildMarkStructure",
value: function buildMarkStructure(content) {
var _this9 = this;
return mergeMarks(content.map(function (node) {
var nodeMarks = _this9.getMarks(node);
if (nodeMarks.length === 0) {
return node;
}
return nodeMarks.reverse().reduce(function (acc, mark) {
var eq = mark.eq;
return _objectSpread(_objectSpread({}, mark), {}, {
eq: eq,
content: [acc]
});
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
}, node);
}));
}
}]);
}();
export { ReactSerializer as default };