11import { context_menu , context_menu_close } from "../context_menu" ;
22import { focus_handler } from "../focus-handler" ;
3- import log from "../tiptap" ;
3+ import { log } from "../tiptap" ;
44import LinkExtension from "@tiptap/extension-link" ;
55import dom from "@patternslib/patternslib/src/core/dom" ;
66import events from "@patternslib/patternslib/src/core/events" ;
@@ -15,8 +15,15 @@ function pattern_link_context_menu({ app }) {
1515 return {
1616 name : "tiptap-link-context-menu" ,
1717 trigger : ".tiptap-link-context-menu" ,
18- async init ( $el ) {
18+ init ( $el ) {
1919 const el = $el [ 0 ] ;
20+
21+ if ( dom . get_data ( el , this . name ) ) {
22+ // Prevent double initialization.
23+ return ;
24+ }
25+ dom . set_data ( el , this . name , this ) ;
26+
2027 focus_handler ( el ) ;
2128
2229 const btn_open = el . querySelector ( ".tiptap-open-new-link" ) ;
@@ -28,30 +35,32 @@ function pattern_link_context_menu({ app }) {
2835 if ( attrs ?. href ) {
2936 btn_open . setAttribute ( "href" , attrs . href ) ;
3037 }
31- btn_open . addEventListener (
32- "click" ,
33- ( ) =>
34- ( context_menu_instance = context_menu_close ( {
35- instance : context_menu_instance ,
36- pattern_name : this . name ,
37- } ) )
38- ) ;
38+ btn_open . addEventListener ( "click" , ( ) => {
39+ context_menu_close ( {
40+ instance : context_menu_instance ,
41+ pattern_name : this . name ,
42+ } ) ;
43+ context_menu_instance = null ;
44+ } ) ;
3945 }
4046
4147 btn_edit &&
4248 btn_edit . addEventListener ( "click" , ( ) => {
43- context_menu_instance = context_menu_close ( {
49+ context_menu_close ( {
4450 instance : context_menu_instance ,
4551 pattern_name : this . name ,
4652 } ) ;
53+ context_menu_instance = null ;
4754 app . toolbar . link . click ( ) ;
4855 } ) ;
56+
4957 btn_unlink &&
5058 btn_unlink . addEventListener ( "click" , ( ) => {
51- context_menu_instance = context_menu_close ( {
59+ context_menu_close ( {
5260 instance : context_menu_instance ,
5361 pattern_name : this . name ,
5462 } ) ;
63+ context_menu_instance = null ;
5564 app . editor . chain ( ) . focus ( ) . unsetLink ( ) . run ( ) ;
5665 } ) ;
5766 } ,
@@ -60,10 +69,11 @@ function pattern_link_context_menu({ app }) {
6069
6170async function link_panel ( { app } ) {
6271 // Close eventual opened link context menus.
63- context_menu_instance = context_menu_close ( {
72+ context_menu_close ( {
6473 instance : context_menu_instance ,
6574 pattern_name : "tiptap-link-context-menu" ,
6675 } ) ;
76+ context_menu_instance = null ;
6777
6878 const link_panel = document . querySelector ( app . options . link ?. panel ) ;
6979 if ( ! link_panel ) {
@@ -72,6 +82,11 @@ async function link_panel({ app }) {
7282 }
7383 focus_handler ( link_panel ) ;
7484
85+ // Store the current cursor position.
86+ // While extending the selection below the cursor position is changed and
87+ // we want it back where we left.
88+ const last_cursor_position = app . editor . state . selection . $head . pos ;
89+
7590 const reinit = ( ) => {
7691 const link_href = link_panel . querySelector ( "[name=tiptap-href]" ) ;
7792 const link_text = link_panel . querySelector ( "[name=tiptap-text]" ) ;
@@ -88,8 +103,7 @@ async function link_panel({ app }) {
88103
89104 if ( is_link ) {
90105 // Extend the selection to whole link.
91- // Necessary for link updates below in the update_callback
92- // to get the selection right which is replaced.
106+ // Necessary to get the whole link scope and the correct text.
93107 dont_open_context_menu = true ; // setting a selection on a link would open the context menu.
94108 app . editor . commands . extendMarkRange ( "link" ) ;
95109 dont_open_context_menu = false ;
@@ -121,9 +135,6 @@ async function link_panel({ app }) {
121135
122136 const update_callback = ( set_focus ) => {
123137 const cmd = app . editor . chain ( ) ;
124- if ( set_focus === true ) {
125- cmd . focus ( ) ;
126- }
127138 const link_text_value = ( link_text ? link_text . value : text_content ) || "" ;
128139 cmd . command ( async ( { tr } ) => {
129140 // create = update
@@ -137,6 +148,10 @@ async function link_panel({ app }) {
137148 . text ( link_text_value )
138149 . mark ( [ mark ] ) ;
139150 tr . replaceSelectionWith ( link_node , false ) ;
151+ if ( set_focus === true ) {
152+ // Set the cursor back to the position where we left.
153+ cmd . focus ( ) . setTextSelection ( last_cursor_position ) ;
154+ }
140155 return true ;
141156 } ) ;
142157 cmd . run ( ) ;
@@ -190,14 +205,20 @@ async function link_panel({ app }) {
190205
191206export function init ( { app, button } ) {
192207 // Initialize modal after it has injected.
193- button . addEventListener ( "pat-modal-ready" , ( ) => {
194- if ( dom . get_data ( app . toolbar_el , "tiptap-instance" , null ) !== app ) {
195- // If this pat-tiptap instance is not the one which was last
196- // focused, just return and do nothing.
197- // This might be due to one toolbar shared by multiple editors.
198- return ;
199- }
200- link_panel ( { app : app } ) ;
208+ button . addEventListener ( "click" , ( ) => {
209+ document . addEventListener (
210+ "pat-modal-ready" ,
211+ ( ) => {
212+ if ( dom . get_data ( app . toolbar_el , "tiptap-instance" , null ) !== app ) {
213+ // If this pat-tiptap instance is not the one which was last
214+ // focused, just return and do nothing.
215+ // This might be due to one toolbar shared by multiple editors.
216+ return ;
217+ }
218+ link_panel ( { app : app } ) ;
219+ } ,
220+ { once : true }
221+ ) ;
201222 } ) ;
202223
203224 app . editor . on ( "selectionUpdate" , async ( ) => {
@@ -208,8 +229,8 @@ export function init({ app, button }) {
208229 ? button . classList . remove ( "disabled" )
209230 : button . classList . add ( "disabled" ) ;
210231
211- // Temporarily don't open the context menu.
212- if ( dont_open_context_menu && ! app . options . link ?. menu ) {
232+ if ( dont_open_context_menu ) {
233+ // Temporarily don't open the context menu.
213234 return ;
214235 }
215236
@@ -219,10 +240,11 @@ export function init({ app, button }) {
219240 if ( ! app . editor . isActive ( "link" ) ) {
220241 if ( context_menu_instance ) {
221242 // If open, close.
222- context_menu_instance = context_menu_close ( {
243+ context_menu_close ( {
223244 instance : context_menu_instance ,
224245 pattern_name : "tiptap-link-context-menu" ,
225246 } ) ;
247+ context_menu_instance = null ;
226248 }
227249 return ;
228250 }
0 commit comments