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