@atlaskit/renderer
Version:
Renderer component
343 lines (336 loc) • 11.2 kB
JavaScript
/* eslint-disable @atlaskit/editor/no-re-export */
// Mapping file
import Loadable from 'react-loadable';
import { UnsupportedBlock, UnsupportedInline } from '@atlaskit/editor-common/ui';
import { fg } from '@atlaskit/platform-feature-flags';
import Blockquote from './blockquote';
import BodiedExtension from './bodiedExtension';
import MultiBodiedExtension from './multiBodiedExtension';
import ExtensionFrame from './extensionFrame';
import BulletList from './bulletList';
import Doc, { DocWithSelectAllTrap } from './doc';
import Extension from './extension';
import HardBreak from './hardBreak';
import Heading from './heading';
import InlineExtension from './inlineExtension';
import LayoutSection from './layoutSection';
import LayoutColumn from './layoutColumn';
import ListItem from './listItem';
import Caption from './caption';
import OrderedList from './orderedList';
import Paragraph from './paragraph';
import Placeholder from './placeholder';
import Rule from './rule';
import Table from './table';
import { TableCell, TableHeader } from './tableCell';
import TableRow from './tableRow';
import UnknownBlock from './unknownBlock';
// Ignored via go/ees005
// eslint-disable-next-line import/no-named-as-default
const WindowedCodeBlock = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_WindowedCodeBlock" */
'./codeBlock/windowedCodeBlock').then(mod => mod.default),
loading: () => null
});
const CodeBlock = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_CodeBlock" */
'./codeBlock/codeBlock').then(mod => mod.default),
loading: () => null
});
const TaskList = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_TaskList" */
'./taskList').then(mod => mod.default),
loading: () => null
});
const TaskItem = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_TaskItem" */
'./taskItem').then(mod => mod.default),
loading: () => null
});
const DecisionList = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_DecisionList" */
'./decisionList').then(mod => mod.default),
loading: () => null
});
const DecisionItem = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_DecisionItem" */
'./decisionItem').then(mod => mod.default),
loading: () => null
});
const Date = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_Date" */
'./date').then(mod => mod.default),
loading: () => null
});
const Status = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_Status" */
'./status').then(mod => mod.default),
loading: () => null
});
const Emoji = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_Emoji" */
'./emoji').then(mod => mod.default),
loading: () => null
});
const Panel = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_Panel" */
'./panel').then(mod => mod.default),
loading: () => null
});
const EmbedCard = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_EmbedCard" */
'./embedCard').then(mod => mod.default),
loading: () => null
});
const InlineCard = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_InlineCard" */
'./inlineCard').then(mod => mod.default),
loading: () => null
});
const BlockCard = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_BlockCard" */
'./blockCard').then(mod => mod.default),
loading: () => null
});
const Media = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_Media" */
'./media').then(mod => mod.default),
loading: () => null
});
const MediaGroup = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_MediaGroup" */
'./mediaGroup').then(mod => mod.default),
loading: () => null
});
const MediaInline = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_MediaInline" */
'./mediaInline').then(mod => mod.default),
loading: () => null
});
const MediaSingle = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_MediaSingle" */
'./mediaSingle').then(mod => mod.default),
loading: () => null
});
const Mention = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_Mention" */
'./mention').then(mod => mod.default),
loading: () => null
});
const Expand = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_Expand" */
'../../ui/Expand').then(mod => mod.default),
loading: () => null
});
const SyncBlockLoader = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_SyncBlock" */
'./syncBlock').then(mod => mod.default),
loading: () => null
});
const BodiedSyncBlock = Loadable({
loader: () => import( /* webpackChunkName: "@atlaskit-internal_renderer-node_BodiedSyncBlock" */'./bodiedSyncBlock').then(mod => mod.default),
loading: () => null
});
export const nodeToReact = {
blockquote: Blockquote,
bulletList: BulletList,
blockCard: BlockCard,
caption: Caption,
date: Date,
decisionItem: DecisionItem,
decisionList: DecisionList,
doc: Doc,
emoji: Emoji,
extension: Extension,
bodiedExtension: BodiedExtension,
multiBodiedExtension: MultiBodiedExtension,
extensionFrame: ExtensionFrame,
hardBreak: HardBreak,
heading: Heading,
inlineCard: InlineCard,
inlineExtension: InlineExtension,
layoutSection: LayoutSection,
layoutColumn: LayoutColumn,
listItem: ListItem,
media: Media,
mediaGroup: MediaGroup,
mediaInline: MediaInline,
mediaSingle: MediaSingle,
mention: Mention,
orderedList: OrderedList,
panel: Panel,
panel_c1: Panel,
paragraph: Paragraph,
placeholder: Placeholder,
rule: Rule,
status: Status,
taskItem: TaskItem,
taskList: TaskList,
table: Table,
tableCell: TableCell,
tableHeader: TableHeader,
tableRow: TableRow,
unknownBlock: UnknownBlock,
unsupportedBlock: UnsupportedBlock,
unsupportedInline: UnsupportedInline,
expand: Expand,
syncBlock: SyncBlockLoader,
bodiedSyncBlock: BodiedSyncBlock,
nestedExpand: Expand,
embedCard: EmbedCard,
blockTaskItem: TaskItem
};
export const toReact = (node, flags, nodeComponents
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) => {
if (node.type.name === 'doc' && (flags === null || flags === void 0 ? void 0 : flags.allowSelectAllTrap) === true) {
return DocWithSelectAllTrap;
}
if (!fg('jfp-magma-ssr-iv-editor-codeblock')) {
if (node.type.name === 'codeBlock') {
if ((flags === null || flags === void 0 ? void 0 : flags.allowWindowedCodeBlock) === true) {
return WindowedCodeBlock;
}
return CodeBlock;
}
}
// Allowing custom components to override those provided in nodeToReact
const nodes = {
...nodeToReact,
...nodeComponents
};
if (fg('jfp-magma-ssr-iv-editor-codeblock')) {
if (node.type.name === 'codeBlock') {
var _nodes$codeBlock;
if ((flags === null || flags === void 0 ? void 0 : flags.allowWindowedCodeBlock) === true) {
var _nodes$windowedCodeBl;
return (_nodes$windowedCodeBl = nodes.windowedCodeBlock) !== null && _nodes$windowedCodeBl !== void 0 ? _nodes$windowedCodeBl : WindowedCodeBlock;
}
return (_nodes$codeBlock = nodes.codeBlock) !== null && _nodes$codeBlock !== void 0 ? _nodes$codeBlock : CodeBlock;
}
}
nodes['multiBodiedExtension'] = MultiBodiedExtension;
return nodes[node.type.name];
};
/*
* Wraps adjacent textnodes in a textWrapper
*
* Input:
* [
* {
* type: 'text',
* text: 'Hello'
* },
* {
* type: 'text',
* text: 'World!',
* marks: [
* {
* type: 'strong'
* }
* ]
* }
* ]
*
* Output:
* [
* {
* type: 'textWrapper',
* content: [
* {
* type: 'text',
* text: 'Hello'
* },
* {
* type: 'text',
* text: 'World!',
* marks: [
* {
* type: 'strong'
* }
* ]
* }
* ]
* }
* ]
*/
export const mergeTextNodes = nodes => {
return nodes.reduce((acc, current) => {
if (!isText(current.type.name)) {
acc.push(current);
return acc;
}
// Append node to previous node, if it was a text wrapper
if (acc.length > 0 && isTextWrapper(acc[acc.length - 1])) {
const textWrapper = acc[acc.length - 1];
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
textWrapper.content.push(current);
textWrapper.nodeSize += current.nodeSize;
} else {
acc.push({
type: {
name: 'textWrapper'
},
content: [current],
nodeSize: current.nodeSize
});
}
return acc;
}, []);
};
export const isText = type => {
return type === 'text';
};
export const isTextWrapper = node => {
return node.type.name === 'textWrapper';
};
export function isTextNode(node) {
return node.type.name === 'text';
}
// Ignored via go/ees005
// eslint-disable-next-line require-unicode-regexp
const whitespaceRegex = /^\s*$/;
/**
* Detects whether a fragment contains a single paragraph node
* whose content satisfies the condition for an emoji block
*/
export const isEmojiDoc = doc => {
if (doc.childCount !== 1) {
return false;
}
const parentNodes = [];
doc.forEach(child => parentNodes.push(child));
const node = parentNodes[0];
return node.type.name === 'paragraph' && isEmojiBlock(node.content);
};
const isEmojiBlock = pnode => {
const content = [];
// Optimisation for long documents - worst case block will be space-emoji-space
if (pnode.childCount > 7) {
return false;
}
pnode.forEach(child => content.push(child));
let emojiCount = 0;
for (let i = 0; i < content.length; ++i) {
const node = content[i];
switch (node.type.name) {
case 'text':
if (node.text && !node.text.match(whitespaceRegex)) {
return false;
}
continue;
case 'emoji':
if (++emojiCount > 3) {
return false;
}
continue;
default:
// Only text and emoji nodes are allowed
return false;
}
}
return emojiCount > 0;
};
export { Blockquote, BodiedExtension, BulletList, BlockCard, Caption, CodeBlock, WindowedCodeBlock, Date, DecisionItem, DecisionList, Doc, DocWithSelectAllTrap, Emoji, Extension, ExtensionFrame, Expand, HardBreak, Heading, ListItem, InlineCard, InlineExtension, LayoutSection, LayoutColumn, Media, MediaGroup, MediaInline, MediaSingle, Mention, MultiBodiedExtension, OrderedList, Panel, Paragraph, Placeholder, Rule, Status, TaskItem, TaskList, Table, TableCell, TableRow, UnknownBlock, EmbedCard };