Improve Editor related bugs and add multiline md (#1507)

* remove shift from editor hotkeys

* fix inline markdown not working

* add block md parser - WIP

* emojify and linkify text without react-parser

* no need to sanitize text when emojify

* parse block markdown in editor output - WIP

* add inline parser option in block md parser

* improve codeblock regex

* ignore html tag when parsing inline md in block md

* add list markdown rule in block parser

* re-generate block markdown on edit

* change copy from inline markdown to markdown

* fix trim reply from body regex

* fix jumbo emoji in reply message

* fix broken list regex in block markdown

* enable markdown by defualt
This commit is contained in:
Ajay Bura 2023-10-27 21:27:22 +11:00 committed by GitHub
parent 72bb5b42af
commit b24f858369
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 425 additions and 160 deletions

View file

@ -1,6 +1,6 @@
/* eslint-disable jsx-a11y/alt-text */
import React, { ReactEventHandler, Suspense, lazy } from 'react';
import parse, {
import {
Element,
Text as DOMText,
HTMLReactParserOptions,
@ -17,12 +17,12 @@ import * as css from '../styles/CustomHtml.css';
import { getMxIdLocalPart, getRoomWithCanonicalAlias } from '../utils/matrix';
import { getMemberDisplayName } from '../utils/room';
import { EMOJI_PATTERN, URL_NEG_LB } from '../utils/regex';
import { sanitizeText } from '../utils/sanitize';
import { getHexcodeForEmoji, getShortcodeFor } from './emoji';
import { replaceMatch } from '../utils/markdown';
const ReactPrism = lazy(() => import('./react-prism/ReactPrism'));
const EMOJI_REG = new RegExp(`${URL_NEG_LB}(${EMOJI_PATTERN})`, 'g');
const EMOJI_REG = new RegExp(`${URL_NEG_LB}(${EMOJI_PATTERN})`);
export const LINKIFY_OPTS: LinkifyOpts = {
attributes: {
@ -35,25 +35,31 @@ export const LINKIFY_OPTS: LinkifyOpts = {
ignoreTags: ['span'],
};
const emojifyParserOptions: HTMLReactParserOptions = {
replace: (domNode) => {
if (domNode instanceof DOMText) {
return <Linkify options={LINKIFY_OPTS}>{domNode.data}</Linkify>;
}
return undefined;
},
const stringToEmojifyJSX = (text: string): (string | JSX.Element)[] => {
const match = text.match(EMOJI_REG);
if (!match) return [text];
const [emoji] = match;
return replaceMatch(
stringToEmojifyJSX,
text,
match,
<span className={css.EmoticonBase}>
<span className={css.Emoticon()} title={getShortcodeFor(getHexcodeForEmoji(emoji))}>
{emoji}
</span>
</span>
);
};
export const emojifyAndLinkify = (unsafeText: string, linkify?: boolean) => {
const emojifyHtml = sanitizeText(unsafeText).replace(
EMOJI_REG,
(emoji) =>
`<span class="${css.EmoticonBase}"><span class="${css.Emoticon()}" title="${getShortcodeFor(
getHexcodeForEmoji(emoji)
)}">${emoji}</span></span>`
);
export const emojifyAndLinkify = (text: string, linkify?: boolean) => {
const emojifyJSX = stringToEmojifyJSX(text);
return <>{parse(emojifyHtml, linkify ? emojifyParserOptions : undefined)}</>;
if (linkify) {
return <Linkify options={LINKIFY_OPTS}>{emojifyJSX}</Linkify>;
}
return emojifyJSX;
};
export const getReactCustomHtmlParser = (
@ -171,6 +177,8 @@ export const getReactCustomHtmlParser = (
if (typeof codeReact === 'string') {
let lang = props.className;
if (lang === 'language-rs') lang = 'language-rust';
else if (lang === 'language-js') lang = 'language-javascript';
else if (lang === 'language-ts') lang = 'language-typescript';
return (
<ErrorBoundary fallback={<code {...props}>{codeReact}</code>}>
<Suspense fallback={<code {...props}>{codeReact}</code>}>