@@ -18,9 +18,9 @@ import {
18
18
imageUploaderEnabled ,
19
19
showImageUploader ,
20
20
} from "../../shared/prosemirror-plugins/image-upload" ;
21
+ import { getCurrentTextNode , getShortcut } from "../../shared/utils" ;
21
22
import type { CommonViewOptions } from "../../shared/view" ;
22
- import { getShortcut } from "../../shared/utils" ;
23
- import { LINK_TOOLTIP_KEY } from "../plugins/link-editor" ;
23
+ import { showLinkEditor } from "../plugins/link-editor" ;
24
24
import { insertParagraphIfAtDocEnd } from "./helpers" ;
25
25
import {
26
26
insertTableColumnAfterCommand ,
@@ -198,30 +198,52 @@ export function insertLinkCommand(
198
198
dispatch : ( tr : Transaction ) => void ,
199
199
view : EditorView
200
200
) : boolean {
201
- if ( state . selection . empty ) return false ;
201
+ // never actually toggle the mark, as that is done in the link editor
202
+ // we do want to *pretend* to, as toggleMark checks for validity
203
+ const valid = toggleMark ( state . schema . marks . link , { href : null } ) (
204
+ state ,
205
+ null
206
+ ) ;
202
207
203
- let linkUrl = null ;
208
+ if ( dispatch && valid ) {
209
+ let selectedText : string ;
210
+ let linkUrl : string ;
204
211
205
- if ( dispatch ) {
206
- const selectedText =
207
- state . selection . content ( ) . content . firstChild ?. textContent ?? null ;
208
- const linkMatch = / ^ h t t p ( s ) ? : \/ \/ \S + $ / . exec ( selectedText ) ;
209
- linkUrl = linkMatch ?. length > 0 ? linkMatch [ 0 ] : "" ;
210
-
211
- // wrap the dispatch function so that we can add additional transactions after toggleMark
212
- const oldDispatch = dispatch ;
213
- dispatch = ( tr ) => {
214
- oldDispatch ( tr ) ;
215
- view . dispatch (
216
- LINK_TOOLTIP_KEY . setEditMode ( true , state , view . state . tr )
212
+ const $anchor = state . selection . $anchor ;
213
+ // if selection is empty, but inside link mark, use the link url/text from it
214
+ if ( state . selection . empty && $anchor . textOffset ) {
215
+ const currentTextNode = getCurrentTextNode ( state ) ;
216
+ const mark = currentTextNode . marks . find (
217
+ ( m ) => m . type === state . schema . marks . link
217
218
) ;
218
- } ;
219
+ if ( mark ) {
220
+ selectedText = currentTextNode . text ;
221
+ linkUrl = mark . attrs . href as string ;
222
+
223
+ // expand the selection so we're editing the entire link
224
+ const pos = $anchor . pos ;
225
+ dispatch (
226
+ state . tr . setSelection (
227
+ TextSelection . create (
228
+ state . doc ,
229
+ pos - $anchor . textOffset ,
230
+ pos - $anchor . textOffset + selectedText . length
231
+ )
232
+ )
233
+ ) ;
234
+ }
235
+ } else {
236
+ selectedText =
237
+ state . selection . content ( ) . content . firstChild ?. textContent ??
238
+ null ;
239
+ const linkMatch = / ^ h t t p ( s ) ? : \/ \/ \S + $ / . exec ( selectedText ) ;
240
+ linkUrl = linkMatch ?. length > 0 ? linkMatch [ 0 ] : "" ;
241
+ }
242
+
243
+ showLinkEditor ( view , linkUrl , selectedText ) ;
219
244
}
220
245
221
- return toggleMark ( state . schema . marks . link , { href : linkUrl } ) (
222
- state ,
223
- dispatch
224
- ) ;
246
+ return valid ;
225
247
}
226
248
227
249
/**
0 commit comments