UNPKG

@atlaskit/renderer

Version:
343 lines (336 loc) • 11.2 kB
/* 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 };