1
- import Vue, { nextTick } from ' vue'
1
+ import Vue from ' vue'
2
2
3
3
` ` ### * @typedef {{label:string,icon?:string,action:()=>any}} ContextMenuEntry ###
4
4
` ` ### * @typedef {{
5
5
oncontextmenu: (this: HTMLElement, ev: MouseEvent) => any
6
- onglobalclick: (ev: MouseEvent) => any
7
- onglobalkeyup: (ev: KeyboardEvent) => any
6
+ destroy: () => any
8
7
entries_provider: (ev: MouseEvent) => ContextMenuEntry[]
9
8
}} ContextMenuData
10
9
###
11
10
12
11
` ` ### * @type {Map<HTMLElement,ContextMenuData>} ###
13
12
context_menu_data_by_el = new Map
14
13
14
+ remove_all_context_menus = =>
15
+ context_menu_data_by_el .forEach (menu) =>
16
+ menu .destroy ()
17
+ document .addEventListener ' contextmenu' , remove_all_context_menus, false
18
+ document .addEventListener ' click' , remove_all_context_menus, false
19
+ document .addEventListener ' keyup' , remove_all_context_menus, false
20
+
15
21
set_context_menu = (### * @type HTMLElement ### el, ### * @type {(ev: MouseEvent)=>ContextMenuEntry[]} ### entries_provider) =>
16
22
existing_context_menu_data = context_menu_data_by_el .get el
17
23
if existing_context_menu_data
@@ -24,7 +30,7 @@ set_context_menu = (###* @type HTMLElement ### el, ###* @type {(ev: MouseEvent)=
24
30
# The element(s) created by this is quite similar to the template of <git-action-button>
25
31
build_context_menu = (### * @type MouseEvent ### event ) =>
26
32
entries = entries_provider (event)
27
- return if not entries
33
+ return if not entries or wrapper_el
28
34
wrapper_el = document .createElement (' ul' )
29
35
wrapper_el .setAttribute (' aria-label' , ' Context menu' )
30
36
wrapper_el .classList .add ' context-menu-wrapper'
@@ -44,35 +50,27 @@ set_context_menu = (###* @type HTMLElement ### el, ###* @type {(ev: MouseEvent)=
44
50
entry_el .onclick = entry .action
45
51
wrapper_el ? .appendChild (entry_el)
46
52
document .body .appendChild (wrapper_el)
47
- destroy_context_menu = =>
48
- return if not wrapper_el
49
- document .body .removeChild (wrapper_el)
50
- wrapper_el = null
51
53
52
54
` ` ### * @type ContextMenuData ###
53
55
context_menu_data =
54
56
oncontextmenu : (e ) =>
55
57
e .preventDefault ()
56
- setTimeout (=> build_context_menu (e)), 0
57
- onglobalclick : destroy_context_menu
58
- onglobalkeyup : destroy_context_menu
58
+ e .stopPropagation ()
59
+ remove_all_context_menus ()
60
+ build_context_menu (e)
61
+ destroy : =>
62
+ return if not wrapper_el
63
+ document .body .removeChild (wrapper_el)
64
+ wrapper_el = null
59
65
entries_provider : entries_provider
60
-
61
66
el .addEventListener ' contextmenu' , context_menu_data .oncontextmenu , false
62
- document .addEventListener ' contextmenu' , context_menu_data .onglobalclick , false
63
- document .addEventListener ' click' , context_menu_data .onglobalclick , false
64
- document .addEventListener ' keyup' , context_menu_data .onglobalkeyup , false
65
-
66
67
context_menu_data_by_el .set el, context_menu_data
67
68
68
69
disable_context_menu = (### * @type {HTMLElement} ### el ) =>
69
70
context_menu_data = context_menu_data_by_el .get el
70
71
if not context_menu_data
71
72
return
72
73
el .removeEventListener ' contextmenu' , context_menu_data .oncontextmenu
73
- document .removeEventListener ' contextmenu' , context_menu_data .onglobalclick
74
- document .removeEventListener ' click' , context_menu_data .onglobalclick
75
- document .removeEventListener ' keyup' , context_menu_data .onglobalkeyup
76
74
context_menu_data_by_el .delete el
77
75
78
76
` ` ### * @type {Vue.Directive} ###
0 commit comments