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

Commit

Permalink
Allow Chrome page translator to translate messages in rooms (#11113)
Browse files Browse the repository at this point in the history
* support message translation in chat

* Update src/HtmlUtils.tsx

* update snapshots

* Convert TextualBody-test to use snapshots

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
Co-authored-by: Richard van der Hoff <richard@matrix.org>
  • Loading branch information
3 people authored Jul 25, 2024
1 parent 3c370c6 commit c1420ba
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 46 deletions.
2 changes: 2 additions & 0 deletions src/HtmlUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,8 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
"mx_EventTile_body": true,
"mx_EventTile_bigEmoji": emojiBody,
"markdown-body": isHtmlMessage && !emojiBody,
// Override the global `notranslate` class set by the top-level `matrixchat` div.
"translate": true,
});

let emojiBodyElements: JSX.Element[] | undefined;
Expand Down
6 changes: 3 additions & 3 deletions test/__snapshots__/HtmlUtils-test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`bodyToHtml does not mistake characters in text presentation mode for emoji 1`] = `
<DocumentFragment>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
↔ ❗︎
Expand All @@ -22,7 +22,7 @@ exports[`bodyToHtml feature_latex_maths should render inline katex 1`] = `"hello
exports[`bodyToHtml generates big emoji for emoji made of multiple characters 1`] = `
<DocumentFragment>
<span
class="mx_EventTile_body mx_EventTile_bigEmoji"
class="mx_EventTile_body mx_EventTile_bigEmoji translate"
dir="auto"
>
<span
Expand Down Expand Up @@ -52,7 +52,7 @@ exports[`bodyToHtml generates big emoji for emoji made of multiple characters 1`
exports[`bodyToHtml should generate big emoji for an emoji-only reply to a message 1`] = `
<DocumentFragment>
<span
class="mx_EventTile_body mx_EventTile_bigEmoji"
class="mx_EventTile_body mx_EventTile_bigEmoji translate"
dir="auto"
>
<span
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ exports[`<MessageEditHistory /> should match the snapshot 1`] = `
class="mx_EventTile_content"
>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
My Great Massage
Expand Down Expand Up @@ -291,7 +291,7 @@ exports[`<MessageEditHistory /> should support events with 1`] = `
class="mx_EventTile_content"
>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
My Great Missage
Expand Down
33 changes: 8 additions & 25 deletions test/components/views/messages/TextualBody-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev });
expect(container).toHaveTextContent("* sender winks");
const content = container.querySelector(".mx_EventTile_body");
expect(content).toContainHTML('<span class="mx_EventTile_body" dir="auto">winks</span>');
expect(content).toMatchSnapshot();
});

it("renders m.notice correctly", () => {
Expand All @@ -155,7 +155,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev });
expect(container).toHaveTextContent(ev.getContent().body);
const content = container.querySelector(".mx_EventTile_body");
expect(content).toContainHTML(`<span class="mx_EventTile_body" dir="auto">${ev.getContent().body}</span>`);
expect(content).toMatchSnapshot();
});

describe("renders plain-text m.text correctly", () => {
Expand All @@ -168,7 +168,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev });
expect(container).toHaveTextContent(ev.getContent().body);
const content = container.querySelector(".mx_EventTile_body");
expect(content).toContainHTML(`<span class="mx_EventTile_body" dir="auto">${ev.getContent().body}</span>`);
expect(content).toMatchSnapshot();
});

// If pills were rendered within a Portal/same shadow DOM then it'd be easier to test
Expand All @@ -177,11 +177,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev });
expect(container).toHaveTextContent(ev.getContent().body);
const content = container.querySelector(".mx_EventTile_body");
expect(content).toContainHTML(
'<span class="mx_EventTile_body" dir="auto">' +
'Visit <a href="https://matrix.org/" class="linkified" target="_blank" rel="noreferrer noopener">' +
"https://matrix.org/</a></span>",
);
expect(content).toMatchSnapshot();
});

it("should not pillify MXIDs", () => {
Expand Down Expand Up @@ -266,11 +262,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev }, matrixClient);
expect(container).toHaveTextContent("foo baz bar del u");
const content = container.querySelector(".mx_EventTile_body");
expect(content).toContainHTML(
'<span class="mx_EventTile_body markdown-body" dir="auto">' +
ev.getContent().formatted_body +
"</span>",
);
expect(content).toMatchSnapshot();
});

it("spoilers get injected properly into the DOM", () => {
Expand All @@ -281,14 +273,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev }, matrixClient);
expect(container).toHaveTextContent("Hey (movie) the movie was awesome");
const content = container.querySelector(".mx_EventTile_body");
expect(content).toContainHTML(
'<span class="mx_EventTile_body markdown-body" dir="auto">' +
"Hey <span>" +
'<button class="mx_EventTile_spoiler">' +
'<span class="mx_EventTile_spoiler_reason">(movie)</span>&nbsp;' +
'<span class="mx_EventTile_spoiler_content"><span>the movie was awesome</span></span>' +
"</span></button></span>",
);
expect(content).toMatchSnapshot();
});

it("linkification is not applied to code blocks", () => {
Expand Down Expand Up @@ -366,7 +351,7 @@ describe("<TextualBody />", () => {
expect(content).toMatchSnapshot();
});

it("renders formatted body without html corretly", () => {
it("renders formatted body without html correctly", () => {
const ev = mkEvent({
type: "m.room.message",
room: "room_id",
Expand All @@ -383,9 +368,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev }, matrixClient);

const content = container.querySelector(".mx_EventTile_body");
expect(content).toContainHTML(
'<span class="mx_EventTile_body" dir="auto">' + "escaped *markdown*" + "</span>",
);
expect(content).toMatchSnapshot();
});
});

Expand Down
121 changes: 113 additions & 8 deletions test/components/views/messages/__snapshots__/TextualBody-test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<TextualBody /> renders formatted m.text correctly italics, bold, underline and strikethrough render as expected 1`] = `
<span
class="mx_EventTile_body markdown-body translate"
dir="auto"
>
foo
<em>
baz
</em>
<strong>
bar
</strong>
<del>
del
</del>
<u>
u
</u>
</span>
`;

exports[`<TextualBody /> renders formatted m.text correctly linkification is not applied to code blocks 1`] = `
<span
class="mx_EventTile_body markdown-body"
class="mx_EventTile_body markdown-body translate"
dir="auto"
>
<p>
Expand Down Expand Up @@ -43,7 +67,7 @@ exports[`<TextualBody /> renders formatted m.text correctly linkification is not

exports[`<TextualBody /> renders formatted m.text correctly pills appear for an MXID permalink 1`] = `
<span
class="mx_EventTile_body markdown-body"
class="mx_EventTile_body markdown-body translate"
dir="auto"
>
Chat with
Expand Down Expand Up @@ -90,7 +114,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for eve
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body markdown-body"
class="mx_EventTile_body markdown-body translate"
dir="auto"
>
See this message
Expand Down Expand Up @@ -139,7 +163,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for roo
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body markdown-body"
class="mx_EventTile_body markdown-body translate"
dir="auto"
>
A
Expand Down Expand Up @@ -189,7 +213,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills do not appear
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body markdown-body"
class="mx_EventTile_body markdown-body translate"
dir="auto"
>
An
Expand All @@ -207,7 +231,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills do not appear

exports[`<TextualBody /> renders formatted m.text correctly pills do not appear in code blocks 1`] = `
<span
class="mx_EventTile_body markdown-body"
class="mx_EventTile_body markdown-body translate"
dir="auto"
>
<p>
Expand Down Expand Up @@ -247,7 +271,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills do not appear

exports[`<TextualBody /> renders formatted m.text correctly pills get injected correctly into the DOM 1`] = `
<span
class="mx_EventTile_body markdown-body"
class="mx_EventTile_body markdown-body translate"
dir="auto"
>
Hey
Expand Down Expand Up @@ -288,13 +312,85 @@ exports[`<TextualBody /> renders formatted m.text correctly pills get injected c
</span>
`;

exports[`<TextualBody /> renders formatted m.text correctly renders formatted body without html correctly 1`] = `
<span
class="mx_EventTile_body translate"
dir="auto"
>
escaped *markdown*
</span>
`;

exports[`<TextualBody /> renders formatted m.text correctly spoilers get injected properly into the DOM 1`] = `
<span
class="mx_EventTile_body markdown-body translate"
dir="auto"
>
Hey
<span>
<button
class="mx_EventTile_spoiler"
>
<span
class="mx_EventTile_spoiler_reason"
>
(movie)
</span>
 
<span
class="mx_EventTile_spoiler_content"
>
<span>
the movie was awesome
</span>
</span>
</button>
</span>
</span>
`;

exports[`<TextualBody /> renders m.emote correctly 1`] = `
<span
class="mx_EventTile_body translate"
dir="auto"
>
winks
</span>
`;

exports[`<TextualBody /> renders m.notice correctly 1`] = `
<span
class="mx_EventTile_body translate"
dir="auto"
>
this is a notice, probably from a bot
</span>
`;

exports[`<TextualBody /> renders plain-text m.text correctly linkification get applied correctly into the DOM 1`] = `
<span
class="mx_EventTile_body translate"
dir="auto"
>
Visit
<a
class="linkified"
href="https://matrix.org/"
rel="noreferrer noopener"
target="_blank"
>
https://matrix.org/
</a>
</span>
`;

exports[`<TextualBody /> renders plain-text m.text correctly should pillify a permalink to a message in the same room with the label »Message from Member« 1`] = `"Visit <span><bdi><a class="mx_Pill mx_EventPill" href="https://matrix.to/#/!room1:example.com/%event_id%"><span aria-label="Profile picture" aria-hidden="true" data-testid="avatar-img" data-type="round" data-color="2" class="_avatar_mcap2_17 mx_BaseAvatar" style="--cpd-avatar-size: 16px;"><img loading="lazy" alt="" src="mxc://avatar.url/image.png" referrerpolicy="no-referrer" class="_image_mcap2_50" data-type="round" width="16px" height="16px"></span><span class="mx_Pill_text">Message from Member</span></a></bdi></span>"`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify a permalink to an event in another room with the label »Message in Room 2« 1`] = `"Visit <span><bdi><a class="mx_Pill mx_EventPill" href="https://matrix.to/#/!room2:example.com/%event_id%"><span aria-label="Avatar" aria-hidden="true" data-testid="avatar-img" data-type="round" data-color="2" class="_avatar_mcap2_17 mx_BaseAvatar" style="--cpd-avatar-size: 16px;"><img loading="lazy" alt="" src="mxc://avatar.url/room.png" referrerpolicy="no-referrer" class="_image_mcap2_50" data-type="round" width="16px" height="16px"></span><span class="mx_Pill_text">Message in Room 2</span></a></bdi></span>"`;
exports[`<TextualBody /> renders plain-text m.text correctly should pillify a permalink to an unknown message in the same room with the label »Message« 1`] = `
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
Visit
Expand All @@ -317,3 +413,12 @@ exports[`<TextualBody /> renders plain-text m.text correctly should pillify a pe
</span>
</span>
`;
exports[`<TextualBody /> renders plain-text m.text correctly simple message renders as expected 1`] = `
<span
class="mx_EventTile_body translate"
dir="auto"
>
this is a plaintext message
</span>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ exports[`<PinnedEventTile /> should render pinned event 1`] = `
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
First pinned message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
Hey you. You're the best!
Expand Down Expand Up @@ -218,7 +218,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
Hey you. You're the best!
Expand Down Expand Up @@ -334,7 +334,7 @@ exports[`<LayoutSwitcher /> should render 1`] = `
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
Hey you. You're the best!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
Hey you. You're the best!
Expand Down Expand Up @@ -361,7 +361,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
Hey you. You're the best!
Expand Down Expand Up @@ -477,7 +477,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body"
class="mx_EventTile_body translate"
dir="auto"
>
Hey you. You're the best!
Expand Down

Large diffs are not rendered by default.

0 comments on commit c1420ba

Please sign in to comment.