1
+ 'use strict' ;
2
+
3
+ // Check if we have Javascript support
4
+ document . querySelector ( ':root' ) . classList . add ( 'has-js' ) ;
5
+
6
+ // Restore user mode preferences
7
+ const kCustomPreference = 'customDarkTheme' ;
8
+ const userSettings = sessionStorage . getItem ( kCustomPreference ) ;
9
+ const themeToggleButton = document . getElementById ( 'theme-toggle-btn' ) ;
10
+ if ( userSettings === null && window . matchMedia ) {
11
+ const mq = window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
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
+ }
22
+ }
23
+ if ( mq . matches ) {
24
+ document . documentElement . classList . add ( 'dark-mode' ) ;
25
+ }
26
+ } else if ( userSettings === 'true' ) {
27
+ document . documentElement . classList . add ( 'dark-mode' ) ;
28
+ }
29
+ if ( themeToggleButton ) {
30
+ themeToggleButton . hidden = false ;
31
+ themeToggleButton . addEventListener ( 'click' , function ( ) {
32
+ sessionStorage . setItem (
33
+ kCustomPreference ,
34
+ document . documentElement . classList . toggle ( 'dark-mode' )
35
+ ) ;
36
+ } ) ;
37
+ }
38
+
39
+ // Handle pickers with click/taps rather than hovers
40
+ const pickers = document . querySelectorAll ( '.picker-header' ) ;
41
+ for ( const picker of pickers ) {
42
+ picker . addEventListener ( 'click' , e => {
43
+ if ( ! e . target . closest ( '.picker' ) ) {
44
+ e . preventDefault ( ) ;
45
+ }
46
+
47
+ if ( picker . classList . contains ( 'expanded' ) ) {
48
+ picker . classList . remove ( 'expanded' ) ;
49
+ } else {
50
+ for ( const other of pickers ) {
51
+ other . classList . remove ( 'expanded' ) ;
52
+ }
53
+
54
+ picker . classList . add ( 'expanded' ) ;
55
+ }
56
+ } ) ;
57
+ }
58
+
59
+ // Track when the header is in sticky position
60
+ const header = document . querySelector ( ".header" ) ;
61
+ let ignoreNextIntersection = false ;
62
+ new IntersectionObserver (
63
+ ( [ e ] ) => {
64
+ const currentStatus = header . classList . contains ( 'is-pinned' ) ;
65
+ const newStatus = e . intersectionRatio < 1 ;
66
+
67
+ // Same status, do nothing
68
+ if ( currentStatus === newStatus ) {
69
+ return ;
70
+ } else if ( ignoreNextIntersection ) {
71
+ ignoreNextIntersection = false ;
72
+ return ;
73
+ }
74
+
75
+ /*
76
+ To avoid flickering, ignore the next change event that is triggered
77
+ as the visible elements in the header change once we pin it.
78
+
79
+ The timer is reset anyway after few milliseconds
80
+ */
81
+ ignoreNextIntersection = true ;
82
+ setTimeout ( ( ) => ignoreNextIntersection = false , 50 ) ;
83
+
84
+ header . classList . toggle ( 'is-pinned' , newStatus ) ;
85
+ } ,
86
+ { threshold : [ 1 ] }
87
+ ) . observe ( header ) ;
0 commit comments