mirror of
https://github.com/revoltchat/revite.git
synced 2024-11-21 22:50:59 -05:00
fix: limit maximum quote depth to 3
This commit is contained in:
parent
34bb2bbc13
commit
4a85dd69cf
3 changed files with 34 additions and 9 deletions
|
@ -3,11 +3,13 @@ import { Suspense, lazy } from "preact/compat";
|
|||
const Renderer = lazy(() => import("./RemarkRenderer"));
|
||||
|
||||
export interface MarkdownProps {
|
||||
content?: string | null;
|
||||
content: string;
|
||||
disallowBigEmoji?: boolean;
|
||||
}
|
||||
|
||||
export default function Markdown(props: MarkdownProps) {
|
||||
if (!props.content) return null;
|
||||
|
||||
return (
|
||||
// @ts-expect-error Typings mis-match.
|
||||
<Suspense fallback={props.content}>
|
||||
|
|
|
@ -15,14 +15,14 @@ import { memo } from "preact/compat";
|
|||
import { useEffect, useMemo, useState } from "preact/hooks";
|
||||
|
||||
import { MarkdownProps } from "./Markdown";
|
||||
import { handlers } from "./hast";
|
||||
import { RenderCodeblock } from "./plugins/Codeblock";
|
||||
import { RenderAnchor } from "./plugins/anchors";
|
||||
import { remarkChannels, RenderChannel } from "./plugins/channels";
|
||||
import { isOnlyEmoji, remarkEmoji, RenderEmoji } from "./plugins/emoji";
|
||||
import { remarkMention, RenderMention } from "./plugins/mentions";
|
||||
import { passThroughComponents } from "./plugins/remarkRegexComponent";
|
||||
import { remarkSpoiler, RenderSpoiler } from "./plugins/spoiler";
|
||||
import { remarkTimestamps, timestampHandler } from "./plugins/timestamps";
|
||||
import { remarkTimestamps } from "./plugins/timestamps";
|
||||
import "./prism";
|
||||
|
||||
/**
|
||||
|
@ -139,10 +139,7 @@ const render = unified()
|
|||
.use(remarkEmoji)
|
||||
.use(remarkMention)
|
||||
.use(remarkRehype, {
|
||||
handlers: {
|
||||
...passThroughComponents("emoji", "spoiler", "mention", "channel"),
|
||||
timestamp: timestampHandler,
|
||||
},
|
||||
handlers,
|
||||
})
|
||||
.use(rehypeKatex, {
|
||||
maxSize: 10,
|
||||
|
@ -173,15 +170,34 @@ const Container = styled.div<{ largeEmoji: boolean }>`
|
|||
--emoji-size: ${(props) => (props.largeEmoji ? "3em" : "1.25em")};
|
||||
`;
|
||||
|
||||
/**
|
||||
* Regex for matching execessive blockquotes
|
||||
*/
|
||||
const RE_QUOTE = /(^[>\s][>\s])[>\s]+([^]+)$/gm;
|
||||
|
||||
/**
|
||||
* Sanitise Markdown input before rendering
|
||||
* @param content Input string
|
||||
* @returns Sanitised string
|
||||
*/
|
||||
function sanitise(content: string) {
|
||||
// Strip excessive blockquote indentation
|
||||
return content.replace(RE_QUOTE, (_, m0, m1) => m0 + m1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remark renderer component
|
||||
*/
|
||||
export default memo(({ content, disallowBigEmoji }: MarkdownProps) => {
|
||||
const sanitisedContent = useMemo(() => sanitise(content), [content]);
|
||||
|
||||
const [Content, setContent] = useState<React.ReactElement>(null!);
|
||||
|
||||
useEffect(() => {
|
||||
render.process(content!).then((file) => setContent(file.result));
|
||||
}, [content]);
|
||||
render
|
||||
.process(sanitisedContent)
|
||||
.then((file) => setContent(file.result));
|
||||
}, [sanitisedContent]);
|
||||
|
||||
const largeEmoji = useMemo(
|
||||
() => !disallowBigEmoji && isOnlyEmoji(content!),
|
||||
|
|
7
src/components/markdown/hast.ts
Normal file
7
src/components/markdown/hast.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { passThroughComponents } from "./plugins/remarkRegexComponent";
|
||||
import { timestampHandler } from "./plugins/timestamps";
|
||||
|
||||
export const handlers = {
|
||||
...passThroughComponents("emoji", "spoiler", "mention", "channel"),
|
||||
timestamp: timestampHandler,
|
||||
};
|
Loading…
Reference in a new issue