diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 1030fe7474758..ed1eb66b97c36 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -647,11 +647,35 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { \ \ - ", + \ + \ + \ + ", static_root_path = page.get_static_root_path(), settings_css = static_files::STATIC_FILES.settings_css, settings_js = static_files::STATIC_FILES.settings_js, - ) + theme_light_css = static_files::STATIC_FILES.theme_light_css, + theme_dark_css = static_files::STATIC_FILES.theme_dark_css, + theme_ayu_css = static_files::STATIC_FILES.theme_ayu_css, + ); + // Pre-load all theme CSS files, so that switching feels seamless. + // + // When loading settings.html as a popover, the equivalent HTML is + // generated in main.js. + for file in &shared.style_files { + if let Ok(theme) = file.basename() { + write!( + buf, + "", + root_path = page.static_root_path.unwrap_or(""), + suffix = page.resource_suffix, + ); + } + } }, &shared.style_files, ); diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 5e8c0e8d10c22..403b5004d6558 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1,20 +1,9 @@ // Local js definitions: /* global addClass, getSettingValue, hasClass, searchState */ -/* global onEach, onEachLazy, removeClass */ +/* global onEach, onEachLazy, removeClass, getVar */ "use strict"; -// Get a value from the rustdoc-vars div, which is used to convey data from -// Rust to the JS. If there is no such element, return null. -function getVar(name) { - const el = document.getElementById("rustdoc-vars"); - if (el) { - return el.attributes["data-" + name].value; - } else { - return null; - } -} - // Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL // for a resource under the root-path, with the resource-suffix. function resourcePath(basename, extension) { @@ -187,6 +176,15 @@ function loadCss(cssUrl) { document.getElementsByTagName("head")[0].appendChild(link); } +function preLoadCss(cssUrl) { + // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload + const link = document.createElement("link"); + link.href = cssUrl; + link.rel = "preload"; + link.as = "style"; + document.getElementsByTagName("head")[0].appendChild(link); +} + (function() { const isHelpPage = window.location.pathname.endsWith("/help.html"); @@ -207,6 +205,23 @@ function loadCss(cssUrl) { // hopefully be loaded when the JS will generate the settings content. loadCss(getVar("static-root-path") + getVar("settings-css")); loadScript(getVar("static-root-path") + getVar("settings-js")); + preLoadCss(getVar("static-root-path") + getVar("theme-light-css")); + preLoadCss(getVar("static-root-path") + getVar("theme-dark-css")); + preLoadCss(getVar("static-root-path") + getVar("theme-ayu-css")); + // Pre-load all theme CSS files, so that switching feels seamless. + // + // When loading settings.html as a standalone page, the equivalent HTML is + // generated in context.rs. + setTimeout(() => { + const themes = getVar("themes").split(","); + for (const theme of themes) { + // if there are no themes, do nothing + // "".split(",") == [""] + if (theme !== "") { + preLoadCss(getVar("root-path") + theme + ".css"); + } + } + }, 0); }; window.searchState = { diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index c72ac254fc08c..c3fed9a72d4e2 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -7,7 +7,6 @@ const darkThemes = ["dark", "ayu"]; window.currentTheme = document.getElementById("themeStyle"); -window.mainTheme = document.getElementById("mainThemeStyle"); // WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY // If you update this line, then you also need to update the media query with the same @@ -44,8 +43,6 @@ function getSettingValue(settingName) { const localStoredTheme = getSettingValue("theme"); -const savedHref = []; - // eslint-disable-next-line no-unused-vars function hasClass(elem, className) { return elem && elem.classList && elem.classList.contains(className); @@ -102,6 +99,7 @@ function onEach(arr, func, reversed) { * @param {function(?)} func - The callback * @param {boolean} [reversed] - Whether to iterate in reverse */ +// eslint-disable-next-line no-unused-vars function onEachLazy(lazyArray, func, reversed) { return onEach( Array.prototype.slice.call(lazyArray), @@ -125,30 +123,37 @@ function getCurrentValue(name) { } } -function switchTheme(styleElem, mainStyleElem, newThemeName, saveTheme) { +// Get a value from the rustdoc-vars div, which is used to convey data from +// Rust to the JS. If there is no such element, return null. +const getVar = (function getVar(name) { + const el = document.getElementById("rustdoc-vars"); + if (el) { + return el.attributes["data-" + name].value; + } else { + return null; + } +}); + +function switchTheme(newThemeName, saveTheme) { // If this new value comes from a system setting or from the previously // saved theme, no need to save it. if (saveTheme) { updateLocalStorage("theme", newThemeName); } - if (savedHref.length === 0) { - onEachLazy(document.getElementsByTagName("link"), el => { - savedHref.push(el.href); - }); + let newHref; + + if (newThemeName === "light" || newThemeName === "dark" || newThemeName === "ayu") { + newHref = getVar("static-root-path") + getVar("theme-" + newThemeName + "-css"); + } else { + newHref = getVar("root-path") + newThemeName + getVar("resource-suffix") + ".css"; } - const newHref = savedHref.find(url => { - const m = url.match(/static\.files\/(.*)-[a-f0-9]{16}\.css$/); - if (m && m[1] === newThemeName) { - return true; - } - const m2 = url.match(/\/([^/]*)\.css$/); - if (m2 && m2[1].startsWith(newThemeName)) { - return true; - } - }); - if (newHref && newHref !== styleElem.href) { - styleElem.href = newHref; + + if (!window.currentTheme) { + document.write(``); + window.currentTheme = document.getElementById("themeStyle"); + } else if (newHref !== window.currentTheme.href) { + window.currentTheme.href = newHref; } } @@ -164,7 +169,7 @@ const updateTheme = (function() { */ function updateTheme() { const use = (theme, saveTheme) => { - switchTheme(window.currentTheme, window.mainTheme, theme, saveTheme); + switchTheme(theme, saveTheme); }; // maybe the user has disabled the setting in the meantime! diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index e896850fab6bd..532660e3d33c7 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -17,12 +17,6 @@ {# #} - {# #} - {# #} - {# #} - {% for theme in themes %} - {# #} - {% endfor %} {% if !layout.default_settings.is_empty() %} {# #} {% endif %} +