1.6 KB50 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import {useAtomValue} from 'jotai';
9import {cached} from 'shared/LRU';
10import clientToServerAPI from '../ClientToServerAPI';
11import {codeReviewProvider} from '../codeReview/CodeReviewInfo';
12import {atomFamilyWeak, lazyAtom} from '../jotaiUtils';
13
14import './RenderedMarkup.css';
15
16const renderedMarkup = atomFamilyWeak((markup: string) => {
17 // This is an atom to trigger re-render when the server returns.
18 return lazyAtom(get => {
19 const provider = get(codeReviewProvider);
20 if (provider?.enableMessageSyncing !== true) {
21 return null;
22 }
23 return renderMarkupToHTML(markup);
24 }, null);
25});
26
27let requestId = 0;
28
29const renderMarkupToHTML = cached((markup: string): Promise<string> | string => {
30 requestId += 1;
31 const id = requestId;
32 clientToServerAPI.postMessage({type: 'renderMarkup', markup, id});
33 return new Promise(resolve => {
34 clientToServerAPI
35 .nextMessageMatching('renderedMarkup', message => message.id === id)
36 .then(message => resolve(message.html));
37 });
38});
39
40export function RenderMarkup({children}: {children: string}) {
41 const renderedHtml = useAtomValue(renderedMarkup(children));
42 // TODO: We could consider using DOM purify to sanitize this HTML,
43 // though this html is coming directly from a trusted server.
44 return renderedHtml != null ? (
45 <div className="rendered-markup" dangerouslySetInnerHTML={{__html: renderedHtml}} />
46 ) : (
47 <div>{children}</div>
48 );
49}
50