@@ -147,21 +147,28 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
147147 renderedMarkdown = elements . map ( e => typeof e === 'string' ? e : e . outerHTML ) . join ( '' ) ;
148148 }
149149
150- const htmlParser = new DOMParser ( ) ;
151- const markdownHtmlDoc = htmlParser . parseFromString ( sanitizeRenderedMarkdown ( renderedMarkdown , markdown . isTrusted ?? false , options . sanitizerConfig ) as unknown as string , 'text/html' ) ;
150+ const renderedContent = document . createElement ( 'div' ) ;
151+ const sanitizerConfig = getDomSanitizerConfig ( markdown . isTrusted ?? false , options . sanitizerConfig ?? { } ) ;
152+ domSanitize . safeSetInnerHtml ( renderedContent , renderedMarkdown , sanitizerConfig ) ;
152153
153- rewriteRenderedLinks ( markdown , options , markdownHtmlDoc . body ) ;
154+ // Rewrite links and images before potentially inserting them into the real dom
155+ rewriteRenderedLinks ( markdown , options , renderedContent ) ;
154156
155- const element = target ?? document . createElement ( 'div' ) ;
156- element . innerHTML = sanitizeRenderedMarkdown ( markdownHtmlDoc . body . innerHTML , markdown . isTrusted ?? false , options . sanitizerConfig ) as unknown as string ;
157+ let outElement : HTMLElement ;
158+ if ( target ) {
159+ outElement = target ;
160+ DOM . reset ( target , ...renderedContent . children ) ;
161+ } else {
162+ outElement = renderedContent ;
163+ }
157164
158165 if ( codeBlocks . length > 0 ) {
159166 Promise . all ( codeBlocks ) . then ( ( tuples ) => {
160167 if ( isDisposed ) {
161168 return ;
162169 }
163170 const renderedElements = new Map ( tuples ) ;
164- const placeholderElements = element . querySelectorAll < HTMLDivElement > ( `div[data-code]` ) ;
171+ const placeholderElements = outElement . querySelectorAll < HTMLDivElement > ( `div[data-code]` ) ;
165172 for ( const placeholderElement of placeholderElements ) {
166173 const renderedElement = renderedElements . get ( placeholderElement . dataset [ 'code' ] ?? '' ) ;
167174 if ( renderedElement ) {
@@ -172,7 +179,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
172179 } ) ;
173180 } else if ( syncCodeBlocks . length > 0 ) {
174181 const renderedElements = new Map ( syncCodeBlocks ) ;
175- const placeholderElements = element . querySelectorAll < HTMLDivElement > ( `div[data-code]` ) ;
182+ const placeholderElements = outElement . querySelectorAll < HTMLDivElement > ( `div[data-code]` ) ;
176183 for ( const placeholderElement of placeholderElements ) {
177184 const renderedElement = renderedElements . get ( placeholderElement . dataset [ 'code' ] ?? '' ) ;
178185 if ( renderedElement ) {
@@ -183,7 +190,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
183190
184191 // Signal size changes for image tags
185192 if ( options . asyncRenderCallback ) {
186- for ( const img of element . getElementsByTagName ( 'img' ) ) {
193+ for ( const img of outElement . getElementsByTagName ( 'img' ) ) {
187194 const listener = disposables . add ( DOM . addDisposableListener ( img , 'load' , ( ) => {
188195 listener . dispose ( ) ;
189196 options . asyncRenderCallback ! ( ) ;
@@ -193,17 +200,17 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
193200
194201 // Add event listeners for links
195202 if ( options . actionHandler ) {
196- const onClick = options . actionHandler . disposables . add ( new DomEmitter ( element , 'click' ) ) ;
197- const onAuxClick = options . actionHandler . disposables . add ( new DomEmitter ( element , 'auxclick' ) ) ;
203+ const onClick = options . actionHandler . disposables . add ( new DomEmitter ( outElement , 'click' ) ) ;
204+ const onAuxClick = options . actionHandler . disposables . add ( new DomEmitter ( outElement , 'auxclick' ) ) ;
198205 options . actionHandler . disposables . add ( Event . any ( onClick . event , onAuxClick . event ) ( e => {
199- const mouseEvent = new StandardMouseEvent ( DOM . getWindow ( element ) , e ) ;
206+ const mouseEvent = new StandardMouseEvent ( DOM . getWindow ( outElement ) , e ) ;
200207 if ( ! mouseEvent . leftButton && ! mouseEvent . middleButton ) {
201208 return ;
202209 }
203210 activateLink ( markdown , options , mouseEvent ) ;
204211 } ) ) ;
205212
206- options . actionHandler . disposables . add ( DOM . addDisposableListener ( element , 'keydown' , ( e ) => {
213+ options . actionHandler . disposables . add ( DOM . addDisposableListener ( outElement , 'keydown' , ( e ) => {
207214 const keyboardEvent = new StandardKeyboardEvent ( e ) ;
208215 if ( ! keyboardEvent . equals ( KeyCode . Space ) && ! keyboardEvent . equals ( KeyCode . Enter ) ) {
209216 return ;
@@ -213,7 +220,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
213220 }
214221
215222 // Remove/disable inputs
216- for ( const input of [ ...element . getElementsByTagName ( 'input' ) ] ) {
223+ for ( const input of [ ...outElement . getElementsByTagName ( 'input' ) ] ) {
217224 if ( input . attributes . getNamedItem ( 'type' ) ?. value === 'checkbox' ) {
218225 input . setAttribute ( 'disabled' , '' ) ;
219226 } else {
@@ -227,7 +234,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
227234 }
228235
229236 return {
230- element,
237+ element : outElement ,
231238 dispose : ( ) => {
232239 isDisposed = true ;
233240 disposables . dispose ( ) ;
0 commit comments