@@ -37,48 +37,47 @@ class DetailsMenuElement extends HTMLElement {
37
37
if ( ! summary . hasAttribute ( 'role' ) ) summary . setAttribute ( 'role' , 'button' )
38
38
}
39
39
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 )
49
- }
50
- states . set ( this , state )
51
-
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
- }
40
+ const subscriptions = [
41
+ fromEvent ( details , 'click' , e => shouldCommit ( details , this , e ) ) ,
42
+ fromEvent ( details , 'change' , e => shouldCommit ( details , this , e ) ) ,
43
+ fromEvent ( details , 'keydown' , e => keydown ( details , this , e ) ) ,
44
+ fromEvent ( details , 'toggle' , ( ) => loadFragment ( details , this ) , { once : true } ) ,
45
+ fromEvent ( details , 'toggle' , ( ) => closeCurrentMenu ( details ) ) ,
46
+ this . preload
47
+ ? fromEvent ( details , 'mouseover' , ( ) => loadFragment ( details , this ) , { once : true } )
48
+ : NullSubscription ,
49
+ focusOnOpen ( details )
50
+ ]
51
+
52
+ states . set ( this , { subscriptions, loaded : false } )
60
53
}
61
54
62
55
disconnectedCallback ( ) {
63
56
const state = states . get ( this )
64
57
if ( ! state ) return
65
-
66
58
states . delete ( this )
67
-
68
- const { details, subscriptions} = state
69
- for ( const sub of subscriptions ) {
59
+ for ( const sub of state . subscriptions ) {
70
60
sub . unsubscribe ( )
71
61
}
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 } )
78
62
}
79
63
}
80
64
81
65
const states = new WeakMap ( )
66
+ const NullSubscription = { unsubscribe ( ) { } }
67
+
68
+ function fromEvent (
69
+ target : EventTarget ,
70
+ eventName : string ,
71
+ onNext : EventHandler ,
72
+ options : EventListenerOptionsOrUseCapture = false
73
+ ) {
74
+ target . addEventListener ( eventName , onNext , options )
75
+ return {
76
+ unsubscribe : ( ) => {
77
+ target . removeEventListener ( eventName , onNext , options )
78
+ }
79
+ }
80
+ }
82
81
83
82
function loadFragment ( details : Element , menu : DetailsMenuElement ) {
84
83
const src = menu . getAttribute ( 'src' )
@@ -217,7 +216,8 @@ function commit(selected: Element, details: Element) {
217
216
)
218
217
}
219
218
220
- function keydown ( details : Element , menu : DetailsMenuElement , event : KeyboardEvent ) {
219
+ function keydown ( details : Element , menu : DetailsMenuElement , event : Event ) {
220
+ if ( ! ( event instanceof KeyboardEvent ) ) return
221
221
const isSummaryFocused = event . target instanceof Element && event . target . tagName === 'SUMMARY'
222
222
223
223
// Ignore key presses from nested details.
0 commit comments