@@ -37,17 +37,26 @@ class DetailsMenuElement extends HTMLElement {
37
37
if ( ! summary . hasAttribute ( 'role' ) ) summary . setAttribute ( 'role' , 'button' )
38
38
}
39
39
40
- details . addEventListener ( 'click' , shouldCommit )
41
- details . addEventListener ( 'change' , shouldCommit )
42
- details . addEventListener ( 'keydown' , keydown )
43
- details . addEventListener ( 'toggle' , loadFragment , { once : true } )
44
- details . addEventListener ( 'toggle' , closeCurrentMenu )
45
- if ( this . preload ) {
46
- details . addEventListener ( 'mouseover' , loadFragment , { once : true } )
40
+ const subscriptions = [ focusOnOpen ( details ) ]
41
+ const state = {
42
+ details,
43
+ subscriptions,
44
+ loaded : false ,
45
+ shouldCommit : shouldCommit . bind ( null , details , this ) ,
46
+ keydown : keydown . bind ( null , details , this ) ,
47
+ loadFragment : loadFragment . bind ( null , details , this ) ,
48
+ closeCurrentMenu : closeCurrentMenu . bind ( null , details )
47
49
}
50
+ states . set ( this , state )
48
51
49
- const subscriptions = [ focusOnOpen ( details ) ]
50
- states . set ( this , { details, subscriptions, loaded : false } )
52
+ details . addEventListener ( 'click' , state . shouldCommit )
53
+ details . addEventListener ( 'change' , state . shouldCommit )
54
+ details . addEventListener ( 'keydown' , state . keydown )
55
+ details . addEventListener ( 'toggle' , state . loadFragment , { once : true } )
56
+ details . addEventListener ( 'toggle' , state . closeCurrentMenu )
57
+ if ( this . preload ) {
58
+ details . addEventListener ( 'mouseover' , state . loadFragment , { once : true } )
59
+ }
51
60
}
52
61
53
62
disconnectedCallback ( ) {
@@ -60,24 +69,18 @@ class DetailsMenuElement extends HTMLElement {
60
69
for ( const sub of subscriptions ) {
61
70
sub . unsubscribe ( )
62
71
}
63
- details . removeEventListener ( 'click' , shouldCommit )
64
- details . removeEventListener ( 'change' , shouldCommit )
65
- details . removeEventListener ( 'keydown' , keydown )
66
- details . removeEventListener ( 'toggle' , loadFragment , { once : true } )
67
- details . removeEventListener ( 'toggle' , closeCurrentMenu )
68
- details . removeEventListener ( 'mouseover' , loadFragment , { once : true } )
72
+ details . removeEventListener ( 'click' , state . shouldCommit )
73
+ details . removeEventListener ( 'change' , state . shouldCommit )
74
+ details . removeEventListener ( 'keydown' , state . keydown )
75
+ details . removeEventListener ( 'toggle' , state . loadFragment , { once : true } )
76
+ details . removeEventListener ( 'toggle' , state . closeCurrentMenu )
77
+ details . removeEventListener ( 'mouseover' , state . loadFragment , { once : true } )
69
78
}
70
79
}
71
80
72
81
const states = new WeakMap ( )
73
82
74
- function loadFragment ( event : Event ) {
75
- const details = event . currentTarget
76
- if ( ! ( details instanceof Element ) ) return
77
-
78
- const menu = details . querySelector ( 'details-menu' )
79
- if ( ! menu ) return
80
-
83
+ function loadFragment ( details : Element , menu : DetailsMenuElement ) {
81
84
const src = menu . getAttribute ( 'src' )
82
85
if ( ! src ) return
83
86
@@ -117,14 +120,12 @@ function focusOnOpen(details: Element) {
117
120
}
118
121
}
119
122
120
- function closeCurrentMenu ( event : Event ) {
121
- const el = event . currentTarget
122
- if ( ! ( el instanceof Element ) ) return
123
- if ( ! el . hasAttribute ( 'open' ) ) return
123
+ function closeCurrentMenu ( details : Element ) {
124
+ if ( ! details . hasAttribute ( 'open' ) ) return
124
125
125
126
for ( const menu of document . querySelectorAll ( 'details[open] > details-menu' ) ) {
126
127
const opened = menu . closest ( 'details' )
127
- if ( opened && opened !== el && ! opened . contains ( el ) ) {
128
+ if ( opened && opened !== details && ! opened . contains ( details ) ) {
128
129
opened . removeAttribute ( 'open' )
129
130
}
130
131
}
@@ -163,13 +164,10 @@ function sibling(details: Element, next: boolean): ?HTMLElement {
163
164
164
165
const ctrlBindings = navigator . userAgent . match ( / M a c i n t o s h / )
165
166
166
- function shouldCommit ( event : Event ) {
167
+ function shouldCommit ( details : Element , menu : DetailsMenuElement , event : Event ) {
167
168
const target = event . target
168
169
if ( ! ( target instanceof Element ) ) return
169
170
170
- const details = event . currentTarget
171
- if ( ! ( details instanceof Element ) ) return
172
-
173
171
// Ignore clicks from nested details.
174
172
if ( target . closest ( 'details' ) !== details ) return
175
173
@@ -219,9 +217,7 @@ function commit(selected: Element, details: Element) {
219
217
)
220
218
}
221
219
222
- function keydown ( event : KeyboardEvent ) {
223
- const details = event . currentTarget
224
- if ( ! ( details instanceof Element ) ) return
220
+ function keydown ( details : Element , menu : DetailsMenuElement , event : KeyboardEvent ) {
225
221
const isSummaryFocused = event . target instanceof Element && event . target . tagName === 'SUMMARY'
226
222
227
223
// Ignore key presses from nested details.
0 commit comments