Don't escape pasted text (#8014)

Signed-off-by: Robin Townsend <robin@robin.town>
This commit is contained in:
Robin 2022-03-10 08:30:43 -05:00 committed by GitHub
parent ec612fa0f1
commit 225581de6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 7 deletions

View file

@ -348,7 +348,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
parts = deserializedParts; parts = deserializedParts;
} else { } else {
const text = event.clipboardData.getData("text/plain"); const text = event.clipboardData.getData("text/plain");
parts = parsePlainTextMessage(text, partCreator); parts = parsePlainTextMessage(text, partCreator, { shouldEscape: false });
} }
this.modifiedFlag = true; this.modifiedFlag = true;
const range = getRangeForSelection(this.editorRef.current, model, document.getSelection()); const range = getRangeForSelection(this.editorRef.current, model, document.getSelection());

View file

@ -52,12 +52,12 @@ function isListChild(n: Node): boolean {
return LIST_TYPES.includes(n.parentNode?.nodeName); return LIST_TYPES.includes(n.parentNode?.nodeName);
} }
function parseAtRoomMentions(text: string, pc: PartCreator): Part[] { function parseAtRoomMentions(text: string, pc: PartCreator, shouldEscape = true): Part[] {
const ATROOM = "@room"; const ATROOM = "@room";
const parts: Part[] = []; const parts: Part[] = [];
text.split(ATROOM).forEach((textPart, i, arr) => { text.split(ATROOM).forEach((textPart, i, arr) => {
if (textPart.length) { if (textPart.length) {
parts.push(...pc.plainWithEmoji(escape(textPart))); parts.push(...pc.plainWithEmoji(shouldEscape ? escape(textPart) : textPart));
} }
// it's safe to never append @room after the last textPart // it's safe to never append @room after the last textPart
// as split will report an empty string at the end if // as split will report an empty string at the end if
@ -261,13 +261,17 @@ function parseHtmlMessage(html: string, pc: PartCreator, isQuotedMessage: boolea
return parts; return parts;
} }
export function parsePlainTextMessage(body: string, pc: PartCreator, isQuotedMessage?: boolean): Part[] { export function parsePlainTextMessage(
body: string,
pc: PartCreator,
opts: { isQuotedMessage?: boolean, shouldEscape?: boolean },
): Part[] {
const lines = body.split(/\r\n|\r|\n/g); // split on any new-line combination not just \n, collapses \r\n const lines = body.split(/\r\n|\r|\n/g); // split on any new-line combination not just \n, collapses \r\n
return lines.reduce((parts, line, i) => { return lines.reduce((parts, line, i) => {
if (isQuotedMessage) { if (opts.isQuotedMessage) {
parts.push(pc.plain("> ")); parts.push(pc.plain("> "));
} }
parts.push(...parseAtRoomMentions(line, pc)); parts.push(...parseAtRoomMentions(line, pc, opts.shouldEscape));
const isLast = i === lines.length - 1; const isLast = i === lines.length - 1;
if (!isLast) { if (!isLast) {
parts.push(pc.newline()); parts.push(pc.newline());
@ -288,7 +292,7 @@ export function parseEvent(event: MatrixEvent, pc: PartCreator, { isQuotedMessag
isRainbow = true; isRainbow = true;
} }
} else { } else {
parts = parsePlainTextMessage(content.body || "", pc, isQuotedMessage); parts = parsePlainTextMessage(content.body || "", pc, { isQuotedMessage });
} }
if (isEmote && isRainbow) { if (isEmote && isRainbow) {