@@ -10,6 +10,7 @@ interface ContextMenuOptions<T> {
1010 items : MenuItem < T > [ ] ;
1111 /** On mobile, if set to `true` then the context menu is shown near the element. If `false` (default), then the context menu is shown at the bottom of the screen. */
1212 forcePositionOnMobile ?: boolean ;
13+ onHide ?: ( ) => void ;
1314}
1415
1516interface MenuSeparatorItem {
@@ -36,15 +37,13 @@ export type ContextMenuEvent = PointerEvent | MouseEvent | JQuery.ContextMenuEve
3637class ContextMenu {
3738 private $widget : JQuery < HTMLElement > ;
3839 private $cover : JQuery < HTMLElement > ;
39- private dateContextMenuOpenedMs : number ;
4040 private options ?: ContextMenuOptions < any > ;
4141 private isMobile : boolean ;
4242
4343 constructor ( ) {
4444 this . $widget = $ ( "#context-menu-container" ) ;
4545 this . $cover = $ ( "#context-menu-cover" ) ;
4646 this . $widget . addClass ( "dropend" ) ;
47- this . dateContextMenuOpenedMs = 0 ;
4847 this . isMobile = utils . isMobile ( ) ;
4948
5049 if ( this . isMobile ) {
@@ -76,8 +75,6 @@ class ContextMenu {
7675 keyboardActionService . updateDisplayedShortcuts ( this . $widget ) ;
7776
7877 this . positionMenu ( ) ;
79-
80- this . dateContextMenuOpenedMs = Date . now ( ) ;
8178 }
8279
8380 positionMenu ( ) {
@@ -186,8 +183,6 @@ class ContextMenu {
186183 return false ;
187184 }
188185
189- this . hide ( ) ;
190-
191186 if ( "handler" in item && item . handler ) {
192187 item . handler ( item , e ) ;
193188 }
@@ -197,6 +192,12 @@ class ContextMenu {
197192 // it's important to stop the propagation especially for sub-menus, otherwise the event
198193 // might be handled again by top-level menu
199194 return false ;
195+ } )
196+ . on ( "mouseup" , ( e ) => {
197+ e . stopPropagation ( ) ;
198+ // Hide the content menu on mouse up to prevent the mouse event from propagating to the elements below.
199+ this . hide ( ) ;
200+ return false ;
200201 } ) ;
201202
202203 if ( "enabled" in item && item . enabled !== undefined && ! item . enabled ) {
@@ -220,27 +221,14 @@ class ContextMenu {
220221 }
221222
222223 async hide ( ) {
223- // this date checking comes from change in FF66 - https://github.com/zadam/trilium/issues/468
224- // "contextmenu" event also triggers "click" event which depending on the timing can close the just opened context menu
225- // we might filter out right clicks, but then it's better if even right clicks close the context menu
226- if ( Date . now ( ) - this . dateContextMenuOpenedMs > 300 ) {
227- // seems like if we hide the menu immediately, some clicks can get propagated to the underlying component
228- // see https://github.com/zadam/trilium/pull/3805 for details
229- await timeout ( 100 ) ;
230- this . $widget . removeClass ( "show" ) ;
231- this . $cover . removeClass ( "show" ) ;
232- $ ( "body" ) . removeClass ( "context-menu-shown" ) ;
233- this . $widget . hide ( ) ;
234- }
224+ this . options ?. onHide ?.( ) ;
225+ this . $widget . removeClass ( "show" ) ;
226+ this . $cover . removeClass ( "show" ) ;
227+ $ ( "body" ) . removeClass ( "context-menu-shown" ) ;
228+ this . $widget . hide ( ) ;
235229 }
236230}
237231
238- function timeout ( ms : number ) {
239- return new Promise ( ( accept , reject ) => {
240- setTimeout ( accept , ms ) ;
241- } ) ;
242- }
243-
244232const contextMenu = new ContextMenu ( ) ;
245233
246234export default contextMenu ;
0 commit comments