@@ -15,6 +15,7 @@ const pathStr = `<svg viewBox="0 0 1024 1024" width="16" height="16" fill="curre
1515export interface HyperLinkState {
1616 at : number ;
1717 url : string ;
18+ anchor : HyperLinkExtensionOptions [ 'anchor' ] ;
1819}
1920
2021class HyperLinkIcon extends WidgetType {
@@ -33,11 +34,12 @@ class HyperLinkIcon extends WidgetType {
3334 wrapper . innerHTML = pathStr ;
3435 wrapper . className = 'cm-hyper-link-icon' ;
3536 wrapper . rel = 'nofollow' ;
36- return wrapper ;
37+ const anchor = this . state . anchor && this . state . anchor ( wrapper ) ;
38+ return anchor || wrapper ;
3739 }
3840}
3941
40- function hyperLinkDecorations ( view : EditorView ) {
42+ function hyperLinkDecorations ( view : EditorView , anchor ?: HyperLinkExtensionOptions [ 'anchor' ] ) {
4143 const widgets : Array < Range < Decoration > > = [ ] ;
4244 for ( const range of view . visibleRanges ) {
4345 syntaxTree ( view . state ) . iterate ( {
@@ -50,6 +52,7 @@ function hyperLinkDecorations(view: EditorView) {
5052 widget : new HyperLinkIcon ( {
5153 at : to ,
5254 url : callExp ,
55+ anchor,
5356 } ) ,
5457 side : 1 ,
5558 } ) ;
@@ -61,7 +64,12 @@ function hyperLinkDecorations(view: EditorView) {
6164 return Decoration . set ( widgets ) ;
6265}
6366
64- const linkDecorator = ( regexp ?: RegExp , matchData ?: Record < string , string > , matchFn ?: ( str : string ) => string ) =>
67+ const linkDecorator = (
68+ regexp ?: RegExp ,
69+ matchData ?: Record < string , string > ,
70+ matchFn ?: ( str : string ) => string ,
71+ anchor ?: HyperLinkExtensionOptions [ 'anchor' ] ,
72+ ) =>
6573 new MatchDecorator ( {
6674 regexp : regexp || / \b ( (?: h t t p s ? | f t p ) : \/ \/ [ ^ \s / $ . ? # ] .[ ^ \s ] * ) \b / gi,
6775 decorate : ( add , from , to , match , view ) => {
@@ -72,36 +80,37 @@ const linkDecorator = (regexp?: RegExp, matchData?: Record<string, string>, matc
7280 }
7381 const start = to ,
7482 end = to ;
75- const linkIcon = new HyperLinkIcon ( { at : start , url : urlStr } ) ;
83+ const linkIcon = new HyperLinkIcon ( { at : start , url : urlStr , anchor } ) ;
7684 add ( start , end , Decoration . widget ( { widget : linkIcon , side : 1 } ) ) ;
7785 } ,
7886 } ) ;
7987
80- export type hyperLinkExtensionOptions = {
88+ export type HyperLinkExtensionOptions = {
8189 regexp ?: RegExp ;
8290 match ?: Record < string , string > ;
8391 handle ?: ( value : string ) => string ;
92+ anchor ?: ( dom : HTMLAnchorElement ) => HTMLAnchorElement ;
8493} ;
8594
86- export function hyperLinkExtension ( { regexp, match, handle } : hyperLinkExtensionOptions = { } ) {
95+ export function hyperLinkExtension ( { regexp, match, handle, anchor } : HyperLinkExtensionOptions = { } ) {
8796 return ViewPlugin . fromClass (
8897 class HyperLinkView {
8998 decorator ?: MatchDecorator ;
9099 decorations : DecorationSet ;
91100 constructor ( view : EditorView ) {
92101 if ( regexp ) {
93- this . decorator = linkDecorator ( regexp , match , handle ) ;
102+ this . decorator = linkDecorator ( regexp , match , handle , anchor ) ;
94103 this . decorations = this . decorator . createDeco ( view ) ;
95104 } else {
96- this . decorations = hyperLinkDecorations ( view ) ;
105+ this . decorations = hyperLinkDecorations ( view , anchor ) ;
97106 }
98107 }
99108 update ( update : ViewUpdate ) {
100109 if ( update . docChanged || update . viewportChanged ) {
101110 if ( regexp && this . decorator ) {
102111 this . decorations = this . decorator . updateDeco ( update , this . decorations ) ;
103112 } else {
104- this . decorations = hyperLinkDecorations ( update . view ) ;
113+ this . decorations = hyperLinkDecorations ( update . view , anchor ) ;
105114 }
106115 }
107116 }
0 commit comments