Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Fix textual message stripping new line #7239

Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions src/HtmlUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { tryTransformPermalinkToLocalHref } from "./utils/permalinks/Permalinks"
import { getEmojiFromUnicode } from "./emoji";
import ReplyChain from "./components/views/elements/ReplyChain";
import { mediaFromMxc } from "./customisations/Media";
import Markdown from './Markdown';

linkifyMatrix(linkify);

Expand Down Expand Up @@ -422,6 +423,7 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
let strippedBody: string;
let safeBody: string;
let isDisplayedWithHtml: boolean;
let hasHtmlWithFormattedBody = false;
// XXX: We sanitize the HTML whilst also highlighting its text nodes, to avoid accidentally trying
// to highlight HTML tags themselves. However, this does mean that we don't highlight textnodes which
// are interrupted by HTML tags (not that we did before) - e.g. foo<span/>bar won't get highlighted
Expand All @@ -445,6 +447,8 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts

let formattedBody = typeof content.formatted_body === 'string' ? content.formatted_body : null;
const plainBody = typeof content.body === 'string' ? content.body : "";
const isPlainTextBody = new Markdown(plainBody).isPlainText();
hasHtmlWithFormattedBody = !isPlainTextBody && isHtmlMessage;

if (opts.stripReplyFallback && formattedBody) formattedBody = ReplyChain.stripHTMLReply(formattedBody);
strippedBody = opts.stripReplyFallback ? ReplyChain.stripPlainReply(plainBody) : plainBody;
Expand All @@ -455,28 +459,28 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
if (isHtmlMessage) {
isDisplayedWithHtml = true;
safeBody = sanitizeHtml(formattedBody, sanitizeParams);
}

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,
});
// @ts-ignore - The types for `replaceWith` wrongly expect
// Cheerio instance to be returned.
phtml('div, span[data-mx-maths!=""]').replaceWith(function(i, e) {
return katex.renderToString(
AllHtmlEntities.decode(phtml(e).attr('data-mx-maths')),
{
throwOnError: false,
// @ts-ignore - `e` can be an Element, not just a Node
displayMode: e.name == 'div',
output: "htmlAndMathml",
});
});
safeBody = phtml.html();
}
if (hasHtmlWithFormattedBody && 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,
});
// @ts-ignore - The types for `replaceWith` wrongly expect
// Cheerio instance to be returned.
phtml('div, span[data-mx-maths!=""]').replaceWith(function(i, e) {
return katex.renderToString(
AllHtmlEntities.decode(phtml(e).attr('data-mx-maths')),
{
throwOnError: false,
// @ts-ignore - `e` can be an Element, not just a Node
displayMode: e.name == 'div',
output: "htmlAndMathml",
});
});
safeBody = phtml.html();
}
} finally {
delete sanitizeParams.textFilter;
Expand Down Expand Up @@ -516,7 +520,7 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
const className = classNames({
'mx_EventTile_body': true,
'mx_EventTile_bigEmoji': emojiBody,
'markdown-body': isHtmlMessage && !emojiBody,
'markdown-body': hasHtmlWithFormattedBody && !emojiBody,
});

return isDisplayedWithHtml ?
Expand Down