From 5e01ba36c9f1037c4cf3e7421413fc6c41f85d05 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 10 May 2022 16:09:41 +0200 Subject: [PATCH 1/4] Improve settings menu display --- src/librustdoc/html/static/css/rustdoc.css | 33 ++++++++ src/librustdoc/html/static/css/themes/ayu.css | 6 +- .../html/static/css/themes/dark.css | 6 +- .../html/static/css/themes/light.css | 6 +- src/librustdoc/html/static/js/settings.js | 82 +++++++++++++------ src/librustdoc/html/templates/page.html | 8 +- 6 files changed, 110 insertions(+), 31 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 0f4d842f4336d..57c2ba8611443 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1404,6 +1404,15 @@ pre.rust { border-radius: 2px; cursor: pointer; } +#settings-menu { + padding: 0; +} +#settings-menu > a { + padding: 5px; + width: 100%; + height: 100%; + display: block; +} @keyframes rotating { from { @@ -1416,6 +1425,30 @@ pre.rust { #settings-menu.rotate img { animation: rotating 2s linear infinite; } +#settings-menu #settings { + position: absolute; + right: 0; + z-index: 1; + display: block; + margin-top: 7px; + border-radius: 3px; + border: 1px solid; +} +#settings-menu #settings .setting-line { + margin: 0.6em; +} +/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */ +#settings-menu #settings::before { + content: ''; + position: absolute; + right: 11px; + border: solid; + border-width: 1px 1px 0 0; + display: inline-block; + padding: 4px; + transform: rotate(-45deg); + top: -5px; +} #help-button { font-family: "Fira Sans", Arial, sans-serif; diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index b1bf06c1865c7..ad8f642152bab 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -5,7 +5,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) /* General structure and fonts */ -body { +body, #settings-menu #settings, #settings-menu #settings::before { background-color: #0f1419; color: #c5c5c5; } @@ -541,6 +541,10 @@ kbd { filter: invert(100); } +#settings-menu #settings, #settings-menu #settings::before { + border-color: #5c6773; +} + #copy-path { color: #fff; } diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 236304ccc9f1b..dc38b04c88789 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -1,4 +1,4 @@ -body { +body, #settings-menu #settings, #settings-menu #settings::before { background-color: #353535; color: #ddd; } @@ -420,6 +420,10 @@ kbd { border-color: #ffb900; } +#settings-menu #settings, #settings-menu #settings::before { + border-color: #d2d2d2; +} + #copy-path { color: #999; } diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index c923902aba2d3..48f67af040e6d 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -1,6 +1,6 @@ /* General structure and fonts */ -body { +body, #settings-menu #settings, #settings-menu #settings::before { background-color: white; color: black; } @@ -405,6 +405,10 @@ kbd { border-color: #717171; } +#settings-menu #settings, #settings-menu #settings::before { + border-color: #DDDDDD; +} + #copy-path { color: #999; } diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index ad32a19389389..df828b5ce4c3a 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -1,7 +1,7 @@ // Local js definitions: /* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme */ -/* global addClass, removeClass, onEach, onEachLazy, NOT_DISPLAYED_ID */ -/* global MAIN_ID, getVar, getSettingsButton, switchDisplayedElement, getNotDisplayedElem */ +/* global addClass, removeClass, onEach, onEachLazy */ +/* global MAIN_ID, getVar, getSettingsButton */ "use strict"; @@ -206,38 +206,60 @@ ]; // Then we build the DOM. - const el = document.createElement("section"); - el.id = "settings"; - let innerHTML = ` -
+ let innerHTML = ""; + let elementKind = "div"; + + if (isSettingsPage) { + elementKind = "section"; + innerHTML = `

Rustdoc settings

- `; - - if (isSettingsPage) { - innerHTML += - "Back"; - } else { - innerHTML += "Back"; + + Back + +
`; } - innerHTML += ` -
-
${buildSettingsPageSections(settings)}
`; + innerHTML += `
${buildSettingsPageSections(settings)}
`; + const el = document.createElement(elementKind); + el.id = "settings"; el.innerHTML = innerHTML; if (isSettingsPage) { document.getElementById(MAIN_ID).appendChild(el); } else { - getNotDisplayedElem().appendChild(el); + el.setAttribute("tabindex", "-1"); + getSettingsButton().appendChild(el); } return el; } const settingsMenu = buildSettingsPage(); + function displaySettings() { + settingsMenu.style.display = ""; + } + + function elemIsInParent(elem, parent) { + while (elem && elem !== document.body) { + if (elem === parent) { + return true; + } + elem = elem.parentElement; + } + return false; + } + + function blurHandler(event) { + const settingsButton = getSettingsButton(); + if (!elemIsInParent(document.activeElement, settingsButton) && + !elemIsInParent(event.relatedTarget, settingsButton)) + { + window.hideSettings(); + } + } + if (isSettingsPage) { // We replace the existing "onclick" callback to do nothing if clicked. getSettingsButton().onclick = function(event) { @@ -246,17 +268,27 @@ } else { // We replace the existing "onclick" callback. const settingsButton = getSettingsButton(); + const settingsMenu = document.getElementById("settings"); + window.hideSettings = function() { + settingsMenu.style.display = "none"; + }; settingsButton.onclick = function(event) { + if (elemIsInParent(event.target, settingsMenu)) { + return; + } event.preventDefault(); - if (settingsMenu.parentElement.id === NOT_DISPLAYED_ID) { - switchDisplayedElement(settingsMenu); - } else { + if (settingsMenu.style.display !== "none") { window.hideSettings(); + } else { + displaySettings(); } }; - window.hideSettings = function() { - switchDisplayedElement(null); - }; + settingsButton.onblur = blurHandler; + settingsButton.querySelector("a").onblur = blurHandler; + onEachLazy(settingsMenu.querySelectorAll("input"), el => { + el.onblur = blurHandler; + }); + settingsMenu.onblur = blurHandler; } // We now wait a bit for the web browser to end re-computing the DOM... @@ -264,7 +296,7 @@ setEvents(settingsMenu); // The setting menu is already displayed if we're on the settings page. if (!isSettingsPage) { - switchDisplayedElement(settingsMenu); + displaySettings(); } removeClass(getSettingsButton(), "rotate"); }, 0); diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 470cce93a5020..e57d08c9456e1 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -126,10 +126,12 @@

placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#} type="search"> {#- -#} {#- -#} - {#- -#} - Change settings + {#- -#} + Change settings {#- -#} - {#- -#} + {#- -#} + {#- -#} {#- -#} {#- -#} From e8762757c3628eed11bd94db07dc0bc94542899a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 11 May 2022 23:11:18 +0200 Subject: [PATCH 2/4] Remove theme picker button --- src/librustdoc/html/markdown.rs | 2 - src/librustdoc/html/render/write_shared.rs | 1 - src/librustdoc/html/static/css/noscript.css | 4 - src/librustdoc/html/static/css/rustdoc.css | 22 +-- src/librustdoc/html/static/css/themes/ayu.css | 13 +- .../html/static/css/themes/dark.css | 11 +- .../html/static/css/themes/light.css | 11 +- src/librustdoc/html/static/js/main.js | 137 +----------------- src/librustdoc/html/static_files.rs | 3 - src/librustdoc/html/templates/page.html | 7 - 10 files changed, 12 insertions(+), 199 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 56a085c298250..5ba3bdc12eda6 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1448,8 +1448,6 @@ fn init_id_map() -> FxHashMap, usize> { // used in tera template files). map.insert("mainThemeStyle".into(), 1); map.insert("themeStyle".into(), 1); - map.insert("theme-picker".into(), 1); - map.insert("theme-choices".into(), 1); map.insert("settings-menu".into(), 1); map.insert("help-button".into(), 1); map.insert("main-content".into(), 1); diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 68f2a54ddeb05..702bccb45cf93 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -238,7 +238,6 @@ pub(super) fn write_shared( write_toolchain("favicon-16x16.png", static_files::RUST_FAVICON_PNG_16)?; write_toolchain("favicon-32x32.png", static_files::RUST_FAVICON_PNG_32)?; } - write_toolchain("brush.svg", static_files::BRUSH_SVG)?; write_toolchain("wheel.svg", static_files::WHEEL_SVG)?; write_toolchain("clipboard.svg", static_files::CLIPBOARD_SVG)?; write_toolchain("down-arrow.svg", static_files::DOWN_ARROW_SVG)?; diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index e35358c564993..0a19a99abf054 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -18,7 +18,3 @@ rules. /* The search bar and related controls don't work without JS */ display: none; } - -#theme-picker { - display: none; -} diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 57c2ba8611443..38e67c233d698 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1379,25 +1379,15 @@ pre.rust { margin-bottom: 6px; } -.theme-picker { - position: absolute; - left: -38px; - top: 4px; -} - -.theme-picker button { - outline: none; -} - #settings-menu, #help-button { margin-left: 4px; outline: none; } -#theme-picker, #copy-path { +#copy-path { height: 34px; } -#theme-picker, #settings-menu, #help-button, #copy-path { +#settings-menu > a, #help-button, #copy-path { padding: 5px; width: 33px; border: 1px solid; @@ -1422,7 +1412,7 @@ pre.rust { transform: rotate(360deg); } } -#settings-menu.rotate img { +#settings-menu.rotate > a img { animation: rotating 2s linear infinite; } #settings-menu #settings { @@ -1871,12 +1861,6 @@ details.rustdoc-toggle[open] > summary.hideme::after { margin-left: 32px; } - /* Space is at a premium on mobile, so remove the theme-picker icon. */ - #theme-picker { - display: none; - width: 0; - } - .content { margin-left: 0px; } diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index ad8f642152bab..ea0cb5e072696 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -531,13 +531,13 @@ kbd { box-shadow: inset 0 -1px 0 #5c6773; } -#theme-picker, #settings-menu, #help-button { +#settings-menu > a, #help-button { border-color: #5c6773; background-color: #0f1419; color: #fff; } -#theme-picker > img, #settings-menu > img { +#settings-menu > a img { filter: invert(100); } @@ -555,8 +555,7 @@ kbd { filter: invert(100%); } -#theme-picker:hover, #theme-picker:focus, -#settings-menu:hover, #settings-menu:focus, +#settings-menu > a:hover, #settings-menu > a:focus, #help-button:hover, #help-button:focus { border-color: #e0e0e0; } @@ -574,12 +573,6 @@ kbd { background-color: rgba(110, 110, 110, 0.33); } -@media (max-width: 700px) { - #theme-picker { - background: #0f1419; - } -} - .search-results .result-name span.alias { color: #c5c5c5; } diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index dc38b04c88789..1525163f50281 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -408,14 +408,13 @@ kbd { box-shadow: inset 0 -1px 0 #c6cbd1; } -#theme-picker, #settings-menu, #help-button { +#settings-menu > a, #help-button { border-color: #e0e0e0; background: #f0f0f0; color: #000; } -#theme-picker:hover, #theme-picker:focus, -#settings-menu:hover, #settings-menu:focus, +#settings-menu > a:hover, #settings-menu > a:focus, #help-button:hover, #help-button:focus { border-color: #ffb900; } @@ -447,12 +446,6 @@ kbd { background-color: #4e4e4e; } -@media (max-width: 700px) { - #theme-picker { - background: #f0f0f0; - } -} - .search-results .result-name span.alias { color: #fff; } diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 48f67af040e6d..d36a088d38e3f 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -394,13 +394,12 @@ kbd { box-shadow: inset 0 -1px 0 #c6cbd1; } -#theme-picker, #settings-menu, #help-button { +#settings-menu > a, #help-button { border-color: #e0e0e0; background-color: #fff; } -#theme-picker:hover, #theme-picker:focus, -#settings-menu:hover, #settings-menu:focus, +#settings-menu > a:hover, #settings-menu > a:focus, #help-button:hover, #help-button:focus { border-color: #717171; } @@ -432,12 +431,6 @@ kbd { background-color: #eee; } -@media (max-width: 700px) { - #theme-picker { - background: #fff; - } -} - .search-results .result-name span.alias { color: #000; } diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 336223ad28f32..1e4d58db196ad 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1,7 +1,6 @@ // Local js definitions: /* global addClass, getSettingValue, hasClass, searchState */ /* global onEach, onEachLazy, removeClass */ -/* global switchTheme, useSystemTheme */ "use strict"; @@ -109,21 +108,11 @@ function getVirtualKey(ev) { return String.fromCharCode(c); } -const THEME_PICKER_ELEMENT_ID = "theme-picker"; -const THEMES_ELEMENT_ID = "theme-choices"; const MAIN_ID = "main-content"; const SETTINGS_BUTTON_ID = "settings-menu"; const ALTERNATIVE_DISPLAY_ID = "alternative-display"; const NOT_DISPLAYED_ID = "not-displayed"; -function getThemesElement() { - return document.getElementById(THEMES_ELEMENT_ID); -} - -function getThemePickerElement() { - return document.getElementById(THEME_PICKER_ELEMENT_ID); -} - function getSettingsButton() { return document.getElementById(SETTINGS_BUTTON_ID); } @@ -133,74 +122,10 @@ function getNakedUrl() { return window.location.href.split("?")[0].split("#")[0]; } -function showThemeButtonState() { - const themePicker = getThemePickerElement(); - const themeChoices = getThemesElement(); - - themeChoices.style.display = "block"; - themePicker.style.borderBottomRightRadius = "0"; - themePicker.style.borderBottomLeftRadius = "0"; -} - -function hideThemeButtonState() { - const themePicker = getThemePickerElement(); - const themeChoices = getThemesElement(); - - themeChoices.style.display = "none"; - themePicker.style.borderBottomRightRadius = "3px"; - themePicker.style.borderBottomLeftRadius = "3px"; -} - window.hideSettings = () => { // Does nothing by default. }; -// Set up the theme picker list. -(function () { - if (!document.location.href.startsWith("file:///")) { - return; - } - const themeChoices = getThemesElement(); - const themePicker = getThemePickerElement(); - const availableThemes = getVar("themes").split(","); - - removeClass(themeChoices.parentElement, "hidden"); - - function switchThemeButtonState() { - if (themeChoices.style.display === "block") { - hideThemeButtonState(); - } else { - showThemeButtonState(); - } - } - - function handleThemeButtonsBlur(e) { - const active = document.activeElement; - const related = e.relatedTarget; - - if (active.id !== THEME_PICKER_ELEMENT_ID && - (!active.parentNode || active.parentNode.id !== THEMES_ELEMENT_ID) && - (!related || - (related.id !== THEME_PICKER_ELEMENT_ID && - (!related.parentNode || related.parentNode.id !== THEMES_ELEMENT_ID)))) { - hideThemeButtonState(); - } - } - - themePicker.onclick = switchThemeButtonState; - themePicker.onblur = handleThemeButtonsBlur; - availableThemes.forEach(item => { - const but = document.createElement("button"); - but.textContent = item; - but.onclick = () => { - switchTheme(window.currentTheme, window.mainTheme, item, true); - useSystemTheme(false); - }; - but.onblur = handleThemeButtonsBlur; - themeChoices.appendChild(but); - }); -}()); - /** * This function inserts `newNode` after `referenceNode`. It doesn't work if `referenceNode` * doesn't have a parent node. @@ -512,7 +437,7 @@ function loadCss(cssFileName) { ev.preventDefault(); } searchState.defocus(); - hideThemeButtonState(); + window.hideSettings(); } const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; @@ -522,8 +447,6 @@ function loadCss(cssFileName) { return; } - let themePicker; - if (document.activeElement.tagName === "INPUT") { switch (getVirtualKey(ev)) { case "Escape": @@ -553,64 +476,9 @@ function loadCss(cssFileName) { displayHelp(true, ev); break; - case "t": - case "T": - displayHelp(false, ev); - ev.preventDefault(); - themePicker = getThemePickerElement(); - themePicker.click(); - themePicker.focus(); - break; - default: - if (getThemePickerElement().parentNode.contains(ev.target)) { - handleThemeKeyDown(ev); - } - } - } - } - - function handleThemeKeyDown(ev) { - const active = document.activeElement; - const themes = getThemesElement(); - switch (getVirtualKey(ev)) { - case "ArrowUp": - ev.preventDefault(); - if (active.previousElementSibling && ev.target.id !== THEME_PICKER_ELEMENT_ID) { - active.previousElementSibling.focus(); - } else { - showThemeButtonState(); - themes.lastElementChild.focus(); - } - break; - case "ArrowDown": - ev.preventDefault(); - if (active.nextElementSibling && ev.target.id !== THEME_PICKER_ELEMENT_ID) { - active.nextElementSibling.focus(); - } else { - showThemeButtonState(); - themes.firstElementChild.focus(); - } - break; - case "Enter": - case "Return": - case "Space": - if (ev.target.id === THEME_PICKER_ELEMENT_ID && themes.style.display === "none") { - ev.preventDefault(); - showThemeButtonState(); - themes.firstElementChild.focus(); + break; } - break; - case "Home": - ev.preventDefault(); - themes.firstElementChild.focus(); - break; - case "End": - ev.preventDefault(); - themes.lastElementChild.focus(); - break; - // The escape key is handled in handleEscape, not here, - // so that pressing escape will close the menu even if it isn't focused } } @@ -1006,7 +874,6 @@ function loadCss(cssFileName) { const shortcuts = [ ["?", "Show this help dialog"], ["S", "Focus the search field"], - ["T", "Focus the theme picker menu"], ["↑", "Move up in search results"], ["↓", "Move down in search results"], ["← / →", "Switch result tab (when results focused)"], diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index bec5c083fed22..85ca8431d90da 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -41,9 +41,6 @@ crate static SCRAPE_EXAMPLES_JS: &str = include_str!("static/js/scrape-examples. crate static SCRAPE_EXAMPLES_HELP_MD: &str = include_str!("static/scrape-examples-help.md"); -/// The file contents of `brush.svg`, the icon used for the theme-switch button. -crate static BRUSH_SVG: &[u8] = include_bytes!("static/images/brush.svg"); - /// The file contents of `wheel.svg`, the icon used for the settings button. crate static WHEEL_SVG: &[u8] = include_bytes!("static/images/wheel.svg"); diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index e57d08c9456e1..cd672aadd7e93 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -108,13 +108,6 @@

{%- endif -%} {#- -#}