@@ -219,6 +219,17 @@ impl Error {
219219 }
220220}
221221
222+ macro_rules! try_none {
223+ ( $e: expr, $file: expr) => ( {
224+ use std:: io;
225+ match $e {
226+ Some ( e) => e,
227+ None => return Err ( Error :: new( io:: Error :: new( io:: ErrorKind :: Other , "not found" ) ,
228+ $file) )
229+ }
230+ } )
231+ }
232+
222233macro_rules! try_err {
223234 ( $e: expr, $file: expr) => ( {
224235 match $e {
@@ -859,12 +870,75 @@ fn write_shared(cx: &Context,
859870 // Add all the static files. These may already exist, but we just
860871 // overwrite them anyway to make sure that they're fresh and up-to-date.
861872
862- write ( cx. dst . join ( "main.js" ) ,
863- include_bytes ! ( "static/main.js" ) ) ?;
864873 write ( cx. dst . join ( "rustdoc.css" ) ,
865874 include_bytes ! ( "static/rustdoc.css" ) ) ?;
866- write ( cx. dst . join ( "main.css" ) ,
867- include_bytes ! ( "static/styles/main.css" ) ) ?;
875+ let path = cx. shared . src_root . join ( "../librustdoc/html/static/themes" ) ;
876+ let mut themes: Vec < String > = Vec :: new ( ) ;
877+ for entry in try_err ! ( fs:: read_dir( path. clone( ) ) , & path) {
878+ let entry = try_err ! ( entry, & path) ;
879+ let mut content = Vec :: with_capacity ( 100000 ) ;
880+
881+ let mut f = try_err ! ( File :: open( entry. path( ) ) , & entry. path( ) ) ;
882+ try_err ! ( f. read_to_end( & mut content) , & entry. path( ) ) ;
883+ write ( cx. dst . join ( entry. file_name ( ) ) , content. as_slice ( ) ) ?;
884+ themes. push ( try_none ! (
885+ try_none!( entry. path( ) . file_stem( ) , & entry. path( ) ) . to_str( ) ,
886+ & entry. path( ) ) . to_owned ( ) ) ;
887+ }
888+ themes. sort ( ) ;
889+ // To avoid theme switch latencies as much as possible, we put everything theme related
890+ // at the beginning of the html files into another js file.
891+ write ( cx. dst . join ( "theme.js" ) , format ! (
892+ r#"var themes = document.getElementById("theme-choices");
893+ var themePicker = document.getElementById("theme-picker");
894+ themePicker.onclick = function() {{
895+ if (themes.style.display === "block") {{
896+ themes.style.display = "none";
897+ themePicker.style.borderBottomRightRadius = "3px";
898+ themePicker.style.borderBottomLeftRadius = "3px";
899+ }} else {{
900+ themes.style.display = "block";
901+ themePicker.style.borderBottomRightRadius = "0";
902+ themePicker.style.borderBottomLeftRadius = "0";
903+ }}
904+ }};
905+ var currentTheme = document.getElementById("themeStyle");
906+ var mainTheme = document.getElementById("mainThemeStyle");
907+ [{}].forEach(function(item) {{
908+ var div = document.createElement('div');
909+ div.innerHTML = item;
910+ div.onclick = function(el) {{
911+ switchTheme(currentTheme, mainTheme, item);
912+ }};
913+ themes.appendChild(div);
914+ }});
915+
916+ function updateLocalStorage(theme) {{
917+ if (typeof(Storage) !== "undefined") {{
918+ localStorage.theme = theme;
919+ }} else {{
920+ // No Web Storage support so we do nothing
921+ }}
922+ }}
923+ function switchTheme(styleElem, mainStyleElem, newTheme) {{
924+ styleElem.href = mainStyleElem.href.replace("rustdoc.css", newTheme + ".css");
925+ updateLocalStorage(newTheme);
926+ }}
927+ function getCurrentTheme() {{
928+ if (typeof(Storage) !== "undefined" && localStorage.theme !== undefined) {{
929+ return localStorage.theme;
930+ }}
931+ return "main";
932+ }}
933+
934+ switchTheme(currentTheme, mainTheme, getCurrentTheme());
935+ "# , themes. iter( )
936+ . map( |s| format!( "\" {}\" " , s) )
937+ . collect:: <Vec <String >>( )
938+ . join( "," ) ) . as_bytes ( ) ) ?;
939+
940+ write ( cx. dst . join ( "main.js" ) , include_bytes ! ( "static/main.js" ) ) ?;
941+
868942 if let Some ( ref css) = cx. shared . css_file_extension {
869943 let out = cx. dst . join ( "theme.css" ) ;
870944 try_err ! ( fs:: copy( css, out) , css) ;
0 commit comments