@@ -49,6 +49,19 @@ type CopyLabels = {
4949 copied : string
5050}
5151
52+ const urlPattern = / ^ h t t p s ? : \/ \/ [ ^ \s < > ( ) ` " ' ] + $ /
53+
54+ function codeUrl ( text : string ) {
55+ const href = text . trim ( ) . replace ( / [ ) , . ; ! ? ] + $ / , "" )
56+ if ( ! urlPattern . test ( href ) ) return
57+ try {
58+ const url = new URL ( href )
59+ return url . toString ( )
60+ } catch {
61+ return
62+ }
63+ }
64+
5265function createIcon ( path : string , slot : string ) {
5366 const icon = document . createElement ( "div" )
5467 icon . setAttribute ( "data-component" , "icon" )
@@ -110,9 +123,39 @@ function setupCodeCopy(root: HTMLDivElement, labels: CopyLabels) {
110123 wrapper . appendChild ( createCopyButton ( labels ) )
111124 }
112125
126+ const markCodeLinks = ( ) => {
127+ const codeNodes = Array . from ( root . querySelectorAll ( ":not(pre) > code" ) )
128+ for ( const code of codeNodes ) {
129+ const href = codeUrl ( code . textContent ?? "" )
130+ const parentLink =
131+ code . parentElement instanceof HTMLAnchorElement && code . parentElement . classList . contains ( "external-link" )
132+ ? code . parentElement
133+ : null
134+
135+ if ( ! href ) {
136+ if ( parentLink ) parentLink . replaceWith ( code )
137+ continue
138+ }
139+
140+ if ( parentLink ) {
141+ parentLink . href = href
142+ continue
143+ }
144+
145+ const link = document . createElement ( "a" )
146+ link . href = href
147+ link . className = "external-link"
148+ link . target = "_blank"
149+ link . rel = "noopener noreferrer"
150+ code . parentNode ?. replaceChild ( link , code )
151+ link . appendChild ( code )
152+ }
153+ }
154+
113155 const handleClick = async ( event : MouseEvent ) => {
114156 const target = event . target
115157 if ( ! ( target instanceof Element ) ) return
158+
116159 const button = target . closest ( '[data-slot="markdown-copy-button"]' )
117160 if ( ! ( button instanceof HTMLButtonElement ) ) return
118161 const code = button . closest ( '[data-component="markdown-code"]' ) ?. querySelector ( "code" )
@@ -132,6 +175,7 @@ function setupCodeCopy(root: HTMLDivElement, labels: CopyLabels) {
132175 for ( const block of blocks ) {
133176 ensureWrapper ( block )
134177 }
178+ markCodeLinks ( )
135179
136180 const buttons = Array . from ( root . querySelectorAll ( '[data-slot="markdown-copy-button"]' ) )
137181 for ( const button of buttons ) {
0 commit comments