diff --git a/src/HtmlUtils.tsx b/src/HtmlUtils.tsx index 7087386128d..2f085fe5edf 100644 --- a/src/HtmlUtils.tsx +++ b/src/HtmlUtils.tsx @@ -411,8 +411,9 @@ export interface IOptsReturnString extends IOpts { export function bodyToHtml(content: IContent, highlights: string[], opts: IOptsReturnString): string; export function bodyToHtml(content: IContent, highlights: string[], opts: IOptsReturnNode): ReactNode; export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts = {}) { - const isHtmlMessage = content.format === "org.matrix.custom.html" && content.formatted_body; + const isFormattedBody = content.format === "org.matrix.custom.html" && content.formatted_body; let bodyHasEmoji = false; + let isHtmlMessage = false; let sanitizeParams = sanitizeHtmlParams; if (opts.forComposerQuote) { @@ -449,20 +450,23 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts if (opts.stripReplyFallback && formattedBody) formattedBody = ReplyChain.stripHTMLReply(formattedBody); strippedBody = opts.stripReplyFallback ? ReplyChain.stripPlainReply(plainBody) : plainBody; - bodyHasEmoji = mightContainEmoji(isHtmlMessage ? formattedBody : plainBody); + bodyHasEmoji = mightContainEmoji(isFormattedBody ? formattedBody : plainBody); // Only generate safeBody if the message was sent as org.matrix.custom.html - if (isHtmlMessage) { + if (isFormattedBody) { isDisplayedWithHtml = true; + safeBody = sanitizeHtml(formattedBody, sanitizeParams); + const phtml = cheerio.load(safeBody, { + // @ts-ignore: The `_useHtmlParser2` internal option is the + // simplest way to both parse and render using `htmlparser2`. + _useHtmlParser2: true, + decodeEntities: false, + }); + const isPlainText = phtml.html() === phtml.root().text(); + isHtmlMessage = isFormattedBody && !isPlainText; - if (SettingsStore.getValue("feature_latex_maths")) { - const phtml = cheerio.load(safeBody, { - // @ts-ignore: The `_useHtmlParser2` internal option is the - // simplest way to both parse and render using `htmlparser2`. - _useHtmlParser2: true, - decodeEntities: false, - }); + if (isHtmlMessage && SettingsStore.getValue("feature_latex_maths")) { // @ts-ignore - The types for `replaceWith` wrongly expect // Cheerio instance to be returned. phtml('div, span[data-mx-maths!=""]').replaceWith(function(i, e) { diff --git a/test/components/views/messages/TextualBody-test.js b/test/components/views/messages/TextualBody-test.js index 8387b274582..9a83a63efe5 100644 --- a/test/components/views/messages/TextualBody-test.js +++ b/test/components/views/messages/TextualBody-test.js @@ -282,6 +282,30 @@ describe("", () => { '!ZxbRYPQXDXKGmDnJNg:example.com with vias', ); }); + + it('renders formatted body without html corretly', () => { + const ev = mkEvent({ + type: "m.room.message", + room: "room_id", + user: "sender", + content: { + body: "escaped \\*markdown\\*", + msgtype: "m.text", + format: "org.matrix.custom.html", + formatted_body: "escaped *markdown*", + }, + event: true, + }); + + const wrapper = mount(); + + const content = wrapper.find(".mx_EventTile_body"); + expect(content.html()).toBe( + '' + + 'escaped *markdown*' + + '', + ); + }); }); it("renders url previews correctly", () => {