1
1
'use strict' ;
2
2
3
- function setupTheme ( ) {
4
- const kCustomPreference = 'customDarkTheme' ;
5
- const userSettings = sessionStorage . getItem ( kCustomPreference ) ;
6
- const themeToggleButton = document . getElementById ( 'theme-toggle-btn' ) ;
7
-
8
- if ( userSettings === null && window . matchMedia ) {
9
- const mq = window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
10
-
11
- if ( 'onchange' in mq ) {
12
- function mqChangeListener ( e ) {
13
- document . documentElement . classList . toggle ( 'dark-mode' , e . matches ) ;
3
+ {
4
+ function setupTheme ( ) {
5
+ const kCustomPreference = 'customDarkTheme' ;
6
+ const userSettings = sessionStorage . getItem ( kCustomPreference ) ;
7
+ const themeToggleButton = document . getElementById ( 'theme-toggle-btn' ) ;
8
+
9
+ if ( userSettings === null && window . matchMedia ) {
10
+ const mq = window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
11
+
12
+ if ( 'onchange' in mq ) {
13
+ function mqChangeListener ( e ) {
14
+ document . documentElement . classList . toggle ( 'dark-mode' , e . matches ) ;
15
+ }
16
+ mq . addEventListener ( 'change' , mqChangeListener ) ;
17
+ if ( themeToggleButton ) {
18
+ themeToggleButton . addEventListener ( 'click' , function ( ) {
19
+ mq . removeEventListener ( 'change' , mqChangeListener ) ;
20
+ } , { once : true } ) ;
21
+ }
14
22
}
15
- mq . addEventListener ( 'change' , mqChangeListener ) ;
16
- if ( themeToggleButton ) {
17
- themeToggleButton . addEventListener ( 'click' , function ( ) {
18
- mq . removeEventListener ( 'change' , mqChangeListener ) ;
19
- } , { once : true } ) ;
23
+
24
+ if ( mq . matches ) {
25
+ document . documentElement . classList . add ( 'dark-mode' ) ;
20
26
}
27
+ } else if ( userSettings === 'true' ) {
28
+ document . documentElement . classList . add ( 'dark-mode' ) ;
21
29
}
22
30
23
- if ( mq . matches ) {
24
- document . documentElement . classList . add ( 'dark-mode' ) ;
31
+ if ( themeToggleButton ) {
32
+ themeToggleButton . hidden = false ;
33
+ themeToggleButton . addEventListener ( 'click' , function ( ) {
34
+ sessionStorage . setItem (
35
+ kCustomPreference ,
36
+ document . documentElement . classList . toggle ( 'dark-mode' )
37
+ ) ;
38
+ } ) ;
25
39
}
26
- } else if ( userSettings === 'true' ) {
27
- document . documentElement . classList . add ( 'dark-mode' ) ;
28
40
}
29
41
30
- if ( themeToggleButton ) {
31
- themeToggleButton . hidden = false ;
32
- themeToggleButton . addEventListener ( 'click' , function ( ) {
33
- sessionStorage . setItem (
34
- kCustomPreference ,
35
- document . documentElement . classList . toggle ( 'dark-mode' )
36
- ) ;
37
- } ) ;
38
- }
39
- }
42
+ function setupPickers ( ) {
43
+ function closeAllPickers ( ) {
44
+ for ( const picker of pickers ) {
45
+ picker . parentNode . classList . remove ( 'expanded' ) ;
46
+ }
40
47
41
- function setupPickers ( ) {
42
- function closeAllPickers ( ) {
43
- for ( const picker of pickers ) {
44
- picker . parentNode . classList . remove ( 'expanded' ) ;
48
+ window . removeEventListener ( 'click' , closeAllPickers ) ;
49
+ window . removeEventListener ( 'keydown' , onKeyDown ) ;
45
50
}
46
51
47
- window . removeEventListener ( 'click' , closeAllPickers ) ;
48
- window . removeEventListener ( 'keydown' , onKeyDown ) ;
49
- }
52
+ function onKeyDown ( e ) {
53
+ if ( e . key === 'Escape' ) {
54
+ closeAllPickers ( ) ;
55
+ }
56
+ }
57
+
58
+ const pickers = document . querySelectorAll ( '.picker-header > a' ) ;
50
59
51
- function onKeyDown ( e ) {
52
- if ( e . key === 'Escape' ) {
53
- closeAllPickers ( ) ;
60
+ for ( const picker of pickers ) {
61
+ const parentNode = picker . parentNode ;
62
+
63
+ picker . addEventListener ( 'click' , ( e ) => {
64
+ e . preventDefault ( ) ;
65
+
66
+ /*
67
+ closeAllPickers as window event trigger already closed all the pickers,
68
+ if it already closed there is nothing else to do here
69
+ */
70
+ if ( parentNode . classList . contains ( 'expanded' ) ) {
71
+ return ;
72
+ }
73
+
74
+ /*
75
+ In the next frame reopen the picker if needed and also setup events
76
+ to close pickers if needed.
77
+ */
78
+
79
+ requestAnimationFrame ( ( ) => {
80
+ parentNode . classList . add ( 'expanded' ) ;
81
+ window . addEventListener ( 'click' , closeAllPickers ) ;
82
+ window . addEventListener ( 'keydown' , onKeyDown ) ;
83
+ } ) ;
84
+ } ) ;
54
85
}
55
86
}
56
87
57
- const pickers = document . querySelectorAll ( '.picker-header > a' ) ;
58
-
59
- for ( const picker of pickers ) {
60
- const parentNode = picker . parentNode ;
88
+ function setupStickyHeaders ( ) {
89
+ const header = document . querySelector ( '.header' ) ;
90
+ let ignoreNextIntersection = false ;
91
+
92
+ new IntersectionObserver (
93
+ ( [ e ] ) => {
94
+ const currentStatus = header . classList . contains ( 'is-pinned' ) ;
95
+ const newStatus = e . intersectionRatio < 1 ;
96
+
97
+ // Same status, do nothing
98
+ if ( currentStatus === newStatus ) {
99
+ return ;
100
+ } else if ( ignoreNextIntersection ) {
101
+ ignoreNextIntersection = false ;
102
+ return ;
103
+ }
104
+
105
+ /*
106
+ To avoid flickering, ignore the next changes event that is triggered
107
+ as the visible elements in the header change once we pin it.
108
+
109
+ The timer is reset anyway after few milliseconds.
110
+ */
111
+ ignoreNextIntersection = true ;
112
+ setTimeout ( ( ) => {
113
+ ignoreNextIntersection = false ;
114
+ } , 50 ) ;
115
+
116
+ header . classList . toggle ( 'is-pinned' , newStatus ) ;
117
+ } ,
118
+ { threshold : [ 1 ] }
119
+ ) . observe ( header ) ;
120
+ }
61
121
62
- picker . addEventListener ( 'click' , ( e ) => {
63
- e . preventDefault ( ) ;
122
+ function bootstrap ( ) {
123
+ // Check if we have JavaScript support
124
+ document . documentElement . classList . add ( 'has-js' ) ;
64
125
65
- /*
66
- closeAllPickers as window event trigger already closed all the pickers,
67
- if it already closed there is nothing else to do here
68
- */
69
- if ( parentNode . classList . contains ( 'expanded' ) ) {
70
- return ;
71
- }
126
+ // Restore user mode preferences
127
+ setupTheme ( ) ;
72
128
73
- /*
74
- In the next frame reopen the picker if needed and also setup events
75
- to close pickers if needed.
76
- */
129
+ // Handle pickers with click/taps rather than hovers
130
+ setupPickers ( ) ;
77
131
78
- requestAnimationFrame ( ( ) => {
79
- parentNode . classList . add ( 'expanded' ) ;
80
- window . addEventListener ( 'click' , closeAllPickers ) ;
81
- window . addEventListener ( 'keydown' , onKeyDown ) ;
82
- } ) ;
83
- } ) ;
132
+ // Track when the header is in sticky position
133
+ setupStickyHeaders ( ) ;
84
134
}
85
- }
86
-
87
- function setupStickyHeaders ( ) {
88
- const header = document . querySelector ( '.header' ) ;
89
- let ignoreNextIntersection = false ;
90
-
91
- new IntersectionObserver (
92
- ( [ e ] ) => {
93
- const currentStatus = header . classList . contains ( 'is-pinned' ) ;
94
- const newStatus = e . intersectionRatio < 1 ;
95
-
96
- // Same status, do nothing
97
- if ( currentStatus === newStatus ) {
98
- return ;
99
- } else if ( ignoreNextIntersection ) {
100
- ignoreNextIntersection = false ;
101
- return ;
102
- }
103
135
104
- /*
105
- To avoid flickering, ignore the next changes event that is triggered
106
- as the visible elements in the header change once we pin it.
107
-
108
- The timer is reset anyway after few milliseconds.
109
- */
110
- ignoreNextIntersection = true ;
111
- setTimeout ( ( ) => {
112
- ignoreNextIntersection = false ;
113
- } , 50 ) ;
114
-
115
- header . classList . toggle ( 'is-pinned' , newStatus ) ;
116
- } ,
117
- { threshold : [ 1 ] }
118
- ) . observe ( header ) ;
119
- }
120
-
121
- function bootstrap ( ) {
122
- // Check if we have JavaScript support
123
- document . querySelector ( ':root' ) . classList . add ( 'has-js' ) ;
124
-
125
- // Restore user mode preferences
126
- setupTheme ( ) ;
127
-
128
- // Handle pickers with click/taps rather than hovers
129
- setupPickers ( ) ;
130
-
131
- // Track when the header is in sticky position
132
- setupStickyHeaders ( ) ;
133
- }
134
-
135
- if ( document . readyState === 'complete' ) {
136
- bootstrap ( ) ;
137
- } else {
138
- document . addEventListener ( 'DOMContentLoaded' , bootstrap , { once : true } ) ;
139
- }
136
+ if ( document . readyState === 'loading' ) {
137
+ document . addEventListener ( 'DOMContentLoaded' , bootstrap , { once : true } ) ;
138
+ } else {
139
+ bootstrap ( ) ;
140
+ }
141
+ }
0 commit comments