@@ -115,7 +115,22 @@ function setupCodeCopy(root: HTMLDivElement, labels: CopyLabels) {
115115 const parent = block . parentElement
116116 if ( ! parent ) return
117117 const wrapped = parent . getAttribute ( "data-component" ) === "markdown-code"
118- if ( wrapped ) return
118+ if ( wrapped ) {
119+ const buttons = Array . from ( parent . querySelectorAll ( '[data-slot="markdown-copy-button"]' ) ) . filter (
120+ ( el ) : el is HTMLButtonElement => el instanceof HTMLButtonElement ,
121+ )
122+
123+ if ( buttons . length === 0 ) {
124+ parent . appendChild ( createCopyButton ( labels ) )
125+ return
126+ }
127+
128+ for ( const button of buttons . slice ( 1 ) ) {
129+ button . remove ( )
130+ }
131+
132+ return
133+ }
119134 const wrapper = document . createElement ( "div" )
120135 wrapper . setAttribute ( "data-component" , "markdown-code" )
121136 parent . replaceChild ( wrapper , block )
@@ -192,6 +207,20 @@ function setupCodeCopy(root: HTMLDivElement, labels: CopyLabels) {
192207 }
193208}
194209
210+ function wrapCodeBlocks ( root : HTMLDivElement ) {
211+ const blocks = Array . from ( root . querySelectorAll ( "pre" ) )
212+ for ( const block of blocks ) {
213+ const parent = block . parentElement
214+ if ( ! parent ) continue
215+ const wrapped = parent . getAttribute ( "data-component" ) === "markdown-code"
216+ if ( wrapped ) continue
217+ const wrapper = document . createElement ( "div" )
218+ wrapper . setAttribute ( "data-component" , "markdown-code" )
219+ parent . replaceChild ( wrapper , block )
220+ wrapper . appendChild ( block )
221+ }
222+ }
223+
195224function touch ( key : string , value : Entry ) {
196225 cache . delete ( key )
197226 cache . set ( key , value )
@@ -255,12 +284,16 @@ export function Markdown(
255284
256285 const temp = document . createElement ( "div" )
257286 temp . innerHTML = content
287+ wrapCodeBlocks ( temp )
258288
259289 morphdom ( container , temp , {
260290 childrenOnly : true ,
261291 onBeforeElUpdated : ( fromEl , toEl ) => {
262292 if ( fromEl . isEqualNode ( toEl ) ) return false
263- if ( fromEl . getAttribute ( "data-component" ) === "markdown-code" ) {
293+
294+ const fromWrapped = fromEl . getAttribute ( "data-component" ) === "markdown-code"
295+ const toWrapped = toEl . getAttribute ( "data-component" ) === "markdown-code"
296+ if ( fromWrapped && toWrapped ) {
264297 const fromPre = fromEl . querySelector ( "pre" )
265298 const toPre = toEl . querySelector ( "pre" )
266299 if ( fromPre && toPre && ! fromPre . isEqualNode ( toPre ) ) {
@@ -270,13 +303,6 @@ export function Markdown(
270303 }
271304 return true
272305 } ,
273- onBeforeNodeDiscarded : ( node ) => {
274- if ( node instanceof Element ) {
275- if ( node . getAttribute ( "data-slot" ) === "markdown-copy-button" ) return false
276- if ( node . getAttribute ( "data-component" ) === "markdown-code" ) return false
277- }
278- return true
279- } ,
280306 } )
281307
282308 if ( copySetupTimer ) clearTimeout ( copySetupTimer )
0 commit comments