1
1
var darkThemes = [ "dark" , "ayu" ] ;
2
- window . currentTheme = document . getElementById ( "themeStyle" ) ;
3
- window . mainTheme = document . getElementById ( "mainThemeStyle" ) ;
4
2
5
3
var settingsDataset = ( function ( ) {
6
4
var settingsElement = document . getElementById ( "default-settings" ) ;
@@ -30,10 +28,6 @@ function getSettingValue(settingName) {
30
28
return null ;
31
29
}
32
30
33
- var localStoredTheme = getSettingValue ( "theme" ) ;
34
-
35
- var savedHref = [ ] ;
36
-
37
31
// eslint-disable-next-line no-unused-vars
38
32
function hasClass ( elem , className ) {
39
33
return elem && elem . classList && elem . classList . contains ( className ) ;
@@ -104,35 +98,15 @@ function getCurrentValue(name) {
104
98
}
105
99
}
106
100
107
- function switchTheme ( styleElem , mainStyleElem , newTheme , saveTheme ) {
108
- var newHref = mainStyleElem . href . replace (
109
- / \/ r u s t d o c ( [ ^ / ] * ) \. c s s / , "/" + newTheme + "$1" + ".css" ) ;
110
-
111
- // If this new value comes from a system setting or from the previously
112
- // saved theme, no need to save it.
113
- if ( saveTheme ) {
114
- updateLocalStorage ( "rustdoc-theme" , newTheme ) ;
115
- }
116
-
117
- if ( styleElem . href === newHref ) {
118
- return ;
119
- }
101
+ function themeURL ( themeName ) {
102
+ var mainThemeURL = document . getElementById ( "mainThemeStyle" ) . href ;
103
+ return mainThemeURL . replace ( / r u s t d o c ( [ ^ / ] * ) \. c s s / , themeName + "$1.css" ) ;
104
+ }
120
105
121
- var found = false ;
122
- if ( savedHref . length === 0 ) {
123
- onEachLazy ( document . getElementsByTagName ( "link" ) , function ( el ) {
124
- savedHref . push ( el . href ) ;
125
- } ) ;
126
- }
127
- onEach ( savedHref , function ( el ) {
128
- if ( el === newHref ) {
129
- found = true ;
130
- return true ;
131
- }
132
- } ) ;
133
- if ( found ) {
134
- styleElem . href = newHref ;
135
- }
106
+ function useOneTheme ( value ) {
107
+ updateLocalStorage ( "rustdoc-theme" , value ) ;
108
+ useSystemTheme ( false ) ;
109
+ applyThemeUpdate ( ) ;
136
110
}
137
111
138
112
// This function is called from "main.js".
@@ -151,68 +125,105 @@ function useSystemTheme(value) {
151
125
}
152
126
}
153
127
154
- var updateSystemTheme = ( function ( ) {
128
+ // Returns "light" or "dark" depending on the user's browser preferences
129
+ // (that is, independent of any rustdoc settings).
130
+ function getSystemTheme ( ) {
155
131
if ( ! window . matchMedia ) {
156
- // fallback to the CSS computed value
157
- return function ( ) {
158
- var cssTheme = getComputedStyle ( document . documentElement )
159
- . getPropertyValue ( 'content' ) ;
160
-
161
- switchTheme (
162
- window . currentTheme ,
163
- window . mainTheme ,
164
- JSON . parse ( cssTheme ) || "light" ,
165
- true
166
- ) ;
167
- } ;
132
+ // In rustdoc.css we have:
133
+ // @media (prefers-color-scheme: light) {
134
+ // html {
135
+ // content: "light";
136
+ // }
137
+ // }
138
+ // @media (prefers-color-scheme: dark) {
139
+ // html {
140
+ // content: "dark";
141
+ // }
142
+ // }
143
+
144
+ return getComputedStyle ( document . documentElement )
145
+ . getPropertyValue ( 'content' ) || "light" ;
146
+ } else if ( window . matchMedia ( "(prefers-color-scheme: dark)" ) . matches ) {
147
+ return "dark" ;
148
+ } else {
149
+ return "light" ;
168
150
}
151
+ }
169
152
170
- // only listen to (prefers-color-scheme: dark) because light is the default
171
- var mql = window . matchMedia ( "(prefers-color-scheme: dark)" ) ;
172
-
173
- function handlePreferenceChange ( mql ) {
174
- // maybe the user has disabled the setting in the meantime!
175
- if ( getSettingValue ( "use-system-theme" ) !== "false" ) {
176
- var lightTheme = getSettingValue ( "preferred-light-theme" ) || "light" ;
177
- var darkTheme = getSettingValue ( "preferred-dark-theme" ) || "dark" ;
178
-
179
- if ( mql . matches ) {
180
- // prefers a dark theme
181
- switchTheme ( window . currentTheme , window . mainTheme , darkTheme , true ) ;
182
- } else {
183
- // prefers a light theme, or has no preference
184
- switchTheme ( window . currentTheme , window . mainTheme , lightTheme , true ) ;
185
- }
186
-
187
- // note: we save the theme so that it doesn't suddenly change when
188
- // the user disables "use-system-theme" and reloads the page or
189
- // navigates to another page
153
+ // If there is a specific theme selected, or if "Use System Theme" is selected
154
+ // and there is a specific theme for the current light or dark mode, return
155
+ // the appropriate theme's name. Otherwise, return null.
156
+ function getThemeOverride ( ) {
157
+ if ( getSettingValue ( "use-system-theme" ) !== "false" ) {
158
+ var lightOverride = getSettingValue ( "preferred-light-theme" ) ;
159
+ var darkOverride = getSettingValue ( "preferred-dark-theme" ) ;
160
+
161
+ var preferred = getSystemTheme ( ) ;
162
+ if ( preferred == "light" && lightOverride && lightOverride != "light" ) {
163
+ console . log ( "lightoverride " , lightOverride ) ;
164
+ return lightOverride ;
165
+ } else if ( preferred == "dark" && darkOverride && darkOverride != "dark" ) {
166
+ console . log ( "darkoverride " , darkOverride )
167
+ return darkOverride ;
168
+ } else {
169
+ console . log ( "use default" ) ;
170
+ return null ;
190
171
}
172
+ } else {
173
+ console . log ( "getsettingvalue " , getSettingValue ( "theme" ) ) ;
174
+ return getSettingValue ( "theme" ) || null ;
191
175
}
176
+ }
192
177
193
- mql . addListener ( handlePreferenceChange ) ;
194
-
195
- return function ( ) {
196
- handlePreferenceChange ( mql ) ;
197
- } ;
198
- } ) ( ) ;
178
+ const nonDefaultThemeID = "nonDefaultThemeStyle" ;
179
+
180
+ function applyThemeUpdate ( ) {
181
+ var lightOverride = getSettingValue ( "preferred-light-theme" ) ;
182
+ var darkOverride = getSettingValue ( "preferred-dark-theme" ) ;
183
+ var allOverride = getSettingValue ( "theme" ) ;
184
+ if ( allOverride ) {
185
+ document . getElementById ( nonDefaultThemeID ) . href = themeURL ( allOverride ) ;
186
+ } else {
187
+ if ( lightOverride ) {
188
+ document . getElementById ( "lightThemeStyle" ) . href = themeURL ( lightOverride ) ;
189
+ }
190
+ if ( darkOverride ) {
191
+ document . getElementById ( "darkThemeStyle" ) . href = themeURL ( darkOverride ) ;
192
+ }
193
+ document . getElementById ( nonDefaultThemeID ) . href = "" ;
194
+ }
195
+ }
199
196
200
- if ( getSettingValue ( "use-system-theme" ) !== "false" && window . matchMedia ) {
197
+ function updatePreferredDarkTheme ( ) {
201
198
// update the preferred dark theme if the user is already using a dark theme
202
199
// See https://github.com/rust-lang/rust/pull/77809#issuecomment-707875732
200
+ var localStoredTheme = getSettingValue ( "theme" ) ;
203
201
if ( getSettingValue ( "use-system-theme" ) === null
204
202
&& getSettingValue ( "preferred-dark-theme" ) === null
205
203
&& darkThemes . indexOf ( localStoredTheme ) >= 0 ) {
206
204
updateLocalStorage ( "rustdoc-preferred-dark-theme" , localStoredTheme ) ;
207
205
}
206
+ }
208
207
209
- // call the function to initialize the theme at least once!
210
- updateSystemTheme ( ) ;
211
- } else {
212
- switchTheme (
213
- window . currentTheme ,
214
- window . mainTheme ,
215
- getSettingValue ( "theme" ) || "light" ,
216
- false
217
- ) ;
208
+ // If there's a theme override that's not covered by one of the default
209
+ // dark / light themes, we write it to the document head. We use
210
+ // document.write rather than appendChild intentionally. Stylesheets added
211
+ // with document.write are render-blocking, while those added with appendChild
212
+ // are not. We want render blocking behavior to avoid a flash of unstyled
213
+ // content.
214
+ function applyThemeOverride ( ) {
215
+ var override = getThemeOverride ( ) ;
216
+ if ( override ) {
217
+ document . write ( '<link rel="stylesheet" type="text/css" id="' + nonDefaultThemeID +
218
+ '" href="' + themeURL ( override ) + '">' ) ;
219
+ } else {
220
+ document . write ( '<link rel="stylesheet" type="text/css" id="' + nonDefaultThemeID + '">' ) ;
221
+ }
222
+ }
223
+
224
+ updatePreferredDarkTheme ( ) ;
225
+ applyThemeOverride ( ) ;
226
+ if ( window . matchMedia ) {
227
+ var mql = window . matchMedia ( "(prefers-color-scheme: dark)" ) ;
228
+ mql . addEventListener ( 'change' , applyThemeUpdate ) ;
218
229
}
0 commit comments