import { Descendant, Text } from 'slate'; import { sanitizeText } from '../../utils/sanitize'; import { BlockType } from './Elements'; import { CustomElement, FormattedText } from './slate'; const textToCustomHtml = (node: FormattedText): string => { let string = sanitizeText(node.text); if (node.bold) string = `${string}`; if (node.italic) string = `${string}`; if (node.underline) string = `${string}`; if (node.strikeThrough) string = `${string}`; if (node.code) string = `${string}`; if (node.spoiler) string = `${string}`; return string; }; const elementToCustomHtml = (node: CustomElement, children: string): string => { switch (node.type) { case BlockType.Paragraph: return `${children}
`; case BlockType.Heading: return `${children}`; case BlockType.CodeLine: return `${children}\n`; case BlockType.CodeBlock: return `
${children}
`; case BlockType.QuoteLine: return `${children}
`; case BlockType.BlockQuote: return `
${children}
`; case BlockType.ListItem: return `
  • ${children}

  • `; case BlockType.OrderedList: return `
      ${children}
    `; case BlockType.UnorderedList: return ``; case BlockType.Mention: return `${node.name}`; case BlockType.Emoticon: return node.key.startsWith('mxc://') ? `${node.shortcode}` : node.key; case BlockType.Link: return `${node.children}`; default: return children; } }; export const toMatrixCustomHTML = (node: Descendant | Descendant[]): string => { if (Array.isArray(node)) return node.map((n) => toMatrixCustomHTML(n)).join(''); if (Text.isText(node)) return textToCustomHtml(node); const children = node.children.map((n) => toMatrixCustomHTML(n)).join(''); return elementToCustomHtml(node, children); }; const elementToPlainText = (node: CustomElement, children: string): string => { switch (node.type) { case BlockType.Paragraph: return `${children}\n`; case BlockType.Heading: return `${children}\n`; case BlockType.CodeLine: return `${children}\n`; case BlockType.CodeBlock: return `${children}\n`; case BlockType.QuoteLine: return `| ${children}\n`; case BlockType.BlockQuote: return `${children}\n`; case BlockType.ListItem: return `- ${children}\n`; case BlockType.OrderedList: return `${children}\n`; case BlockType.UnorderedList: return `${children}\n`; case BlockType.Mention: return node.id; case BlockType.Emoticon: return node.key.startsWith('mxc://') ? `:${node.shortcode}:` : node.key; case BlockType.Link: return `[${node.children}](${node.href})`; default: return children; } }; export const toPlainText = (node: Descendant | Descendant[]): string => { if (Array.isArray(node)) return node.map((n) => toPlainText(n)).join(''); if (Text.isText(node)) return node.text; const children = node.children.map((n) => toPlainText(n)).join(''); return elementToPlainText(node, children); }; /** * Check if customHtml is equals to plainText * by replacing `
    ` with `/n` in customHtml * and sanitizing plainText before comparison * because text are sanitized in customHtml * @param customHtml string * @param plain string * @returns boolean */ export const customHtmlEqualsPlainText = (customHtml: string, plain: string): boolean => customHtml.replace(//g, '\n') === sanitizeText(plain); export const trimCustomHtml = (customHtml: string) => customHtml.replace(/$/g, '');