@@ -7,7 +7,6 @@ Please see LICENSE files in the repository root for full details.
77*/
88
99import React , { createRef , SyntheticEvent , MouseEvent , StrictMode } from "react" ;
10- import ReactDOM from "react-dom" ;
1110import { MsgType } from "matrix-js-sdk/src/matrix" ;
1211import { TooltipProvider } from "@vector-im/compound-web" ;
1312
@@ -17,8 +16,8 @@ import Modal from "../../../Modal";
1716import dis from "../../../dispatcher/dispatcher" ;
1817import { _t } from "../../../languageHandler" ;
1918import SettingsStore from "../../../settings/SettingsStore" ;
20- import { pillifyLinks , unmountPills } from "../../../utils/pillify" ;
21- import { tooltipifyLinks , unmountTooltips } from "../../../utils/tooltipify" ;
19+ import { pillifyLinks } from "../../../utils/pillify" ;
20+ import { tooltipifyLinks } from "../../../utils/tooltipify" ;
2221import { IntegrationManagers } from "../../../integrations/IntegrationManagers" ;
2322import { isPermalinkHost , tryTransformPermalinkToLocalHref } from "../../../utils/permalinks/Permalinks" ;
2423import { Action } from "../../../dispatcher/actions" ;
@@ -36,6 +35,7 @@ import { EditWysiwygComposer } from "../rooms/wysiwyg_composer";
3635import { IEventTileOps } from "../rooms/EventTile" ;
3736import { MatrixClientPeg } from "../../../MatrixClientPeg" ;
3837import CodeBlock from "./CodeBlock" ;
38+ import { ReactRootManager } from "../../../utils/react" ;
3939
4040interface IState {
4141 // the URLs (if any) to be previewed with a LinkPreviewWidget inside this TextualBody.
@@ -48,9 +48,9 @@ interface IState {
4848export default class TextualBody extends React . Component < IBodyProps , IState > {
4949 private readonly contentRef = createRef < HTMLDivElement > ( ) ;
5050
51- private pills : Element [ ] = [ ] ;
52- private tooltips : Element [ ] = [ ] ;
53- private reactRoots : Element [ ] = [ ] ;
51+ private pills = new ReactRootManager ( ) ;
52+ private tooltips = new ReactRootManager ( ) ;
53+ private reactRoots = new ReactRootManager ( ) ;
5454
5555 private ref = createRef < HTMLDivElement > ( ) ;
5656
@@ -82,7 +82,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
8282 // tooltipifyLinks AFTER calculateUrlPreview because the DOM inside the tooltip
8383 // container is empty before the internal component has mounted so calculateUrlPreview
8484 // won't find any anchors
85- tooltipifyLinks ( [ content ] , this . pills , this . tooltips ) ;
85+ tooltipifyLinks ( [ content ] , [ ... this . pills . elements , ... this . reactRoots . elements ] , this . tooltips ) ;
8686
8787 if ( this . props . mxEvent . getContent ( ) . format === "org.matrix.custom.html" ) {
8888 // Handle expansion and add buttons
@@ -113,12 +113,11 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
113113 private wrapPreInReact ( pre : HTMLPreElement ) : void {
114114 const root = document . createElement ( "div" ) ;
115115 root . className = "mx_EventTile_pre_container" ;
116- this . reactRoots . push ( root ) ;
117116
118117 // Insert containing div in place of <pre> block
119118 pre . parentNode ?. replaceChild ( root , pre ) ;
120119
121- ReactDOM . render (
120+ this . reactRoots . render (
122121 < StrictMode >
123122 < CodeBlock onHeightChanged = { this . props . onHeightChanged } > { pre } </ CodeBlock >
124123 </ StrictMode > ,
@@ -137,16 +136,9 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
137136 }
138137
139138 public componentWillUnmount ( ) : void {
140- unmountPills ( this . pills ) ;
141- unmountTooltips ( this . tooltips ) ;
142-
143- for ( const root of this . reactRoots ) {
144- ReactDOM . unmountComponentAtNode ( root ) ;
145- }
146-
147- this . pills = [ ] ;
148- this . tooltips = [ ] ;
149- this . reactRoots = [ ] ;
139+ this . pills . unmount ( ) ;
140+ this . tooltips . unmount ( ) ;
141+ this . reactRoots . unmount ( ) ;
150142 }
151143
152144 public shouldComponentUpdate ( nextProps : Readonly < IBodyProps > , nextState : Readonly < IState > ) : boolean {
@@ -204,7 +196,8 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
204196 </ StrictMode >
205197 ) ;
206198
207- ReactDOM . render ( spoiler , spoilerContainer ) ;
199+ this . reactRoots . render ( spoiler , spoilerContainer ) ;
200+
208201 node . parentNode ?. replaceChild ( spoilerContainer , node ) ;
209202
210203 node = spoilerContainer ;
0 commit comments