From d635734c78f8f12394ad948e9bf5be68a746dac2 Mon Sep 17 00:00:00 2001 From: meator Date: Sun, 4 May 2025 08:45:35 +0200 Subject: [PATCH 1/3] Force update mdBook theme files This commit is split in two: 1) overwrite the old theme files 2) reapply void-docs' changes to the theme. The next commit applies void-docs changes. This split is done to make the git history clean and to clearly showcase which changes need to be done in the second commit. mdBook v0.4.43 was used to generate the default theme. This update has two benefits: 1. Features added in updates to mdBook made since the old theme files were commited will become available. It is possible to "backport" newer features into the old theme files, but this should be a cleaner solution. 2. It should fix building void-docs using newer versions of mdBook. The currently packaged version of mdBook (v0.4.43) has minor rendering issues. --- src/theme/book.js | 629 +++++++++++++++++++++++++++++++-- src/theme/css/chrome.css | 682 ++++++++++++++++++++++-------------- src/theme/css/general.css | 509 +++++++++++---------------- src/theme/css/print.css | 37 +- src/theme/css/variables.css | 354 +++++++++++++++---- src/theme/index.hbs | 574 +++++++++++++++++------------- 6 files changed, 1824 insertions(+), 961 deletions(-) diff --git a/src/theme/book.js b/src/theme/book.js index d1a280f9e..178f1e902 100644 --- a/src/theme/book.js +++ b/src/theme/book.js @@ -3,31 +3,458 @@ // Fix back button cache problem window.onunload = function () { }; -(function theme() { - var html = document.querySelector("html"); - var themeToggleButton = document.getElementById("theme-toggle"); - - themeToggleButton.addEventListener('click', function sidebarToggle() { - if (html.classList.contains("void-light")) { - html.classList.replace("void-light", "void-dark"); - localStorage.setItem('mdbook-theme', "void-dark"); +// Global variable, shared between modules +function playground_text(playground, hidden = true) { + let code_block = playground.querySelector("code"); + + if (window.ace && code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + return editor.getValue(); + } else if (hidden) { + return code_block.textContent; + } else { + return code_block.innerText; + } +} + +(function codeSnippets() { + function fetch_with_timeout(url, options, timeout = 6000) { + return Promise.race([ + fetch(url, options), + new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)) + ]); + } + + var playgrounds = Array.from(document.querySelectorAll(".playground")); + if (playgrounds.length > 0) { + fetch_with_timeout("https://play.rust-lang.org/meta/crates", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + }) + .then(response => response.json()) + .then(response => { + // get list of crates available in the rust playground + let playground_crates = response.crates.map(item => item["id"]); + playgrounds.forEach(block => handle_crate_list_update(block, playground_crates)); + }); + } + + function handle_crate_list_update(playground_block, playground_crates) { + // update the play buttons after receiving the response + update_play_button(playground_block, playground_crates); + + // and install on change listener to dynamically update ACE editors + if (window.ace) { + let code_block = playground_block.querySelector("code"); + if (code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + editor.addEventListener("change", function (e) { + update_play_button(playground_block, playground_crates); + }); + // add Ctrl-Enter command to execute rust code + editor.commands.addCommand({ + name: "run", + bindKey: { + win: "Ctrl-Enter", + mac: "Ctrl-Enter" + }, + exec: _editor => run_rust_code(playground_block) + }); + } + } + } + + // updates the visibility of play button based on `no_run` class and + // used crates vs ones available on https://play.rust-lang.org + function update_play_button(pre_block, playground_crates) { + var play_button = pre_block.querySelector(".play-button"); + + // skip if code is `no_run` + if (pre_block.querySelector('code').classList.contains("no_run")) { + play_button.classList.add("hidden"); + return; + } + + // get list of `extern crate`'s from snippet + var txt = playground_text(pre_block); + var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; + var snippet_crates = []; + var item; + while (item = re.exec(txt)) { + snippet_crates.push(item[1]); + } + + // check if all used crates are available on play.rust-lang.org + var all_available = snippet_crates.every(function (elem) { + return playground_crates.indexOf(elem) > -1; + }); + + if (all_available) { + play_button.classList.remove("hidden"); } else { - html.classList.replace("void-dark", "void-light"); - localStorage.setItem('mdbook-theme', "void-light"); + play_button.classList.add("hidden"); + } + } + + function run_rust_code(code_block) { + var result_block = code_block.querySelector(".result"); + if (!result_block) { + result_block = document.createElement('code'); + result_block.className = 'result hljs language-bash'; + + code_block.append(result_block); + } + + let text = playground_text(code_block); + let classes = code_block.querySelector('code').classList; + let edition = "2015"; + if(classes.contains("edition2018")) { + edition = "2018"; + } else if(classes.contains("edition2021")) { + edition = "2021"; + } + var params = { + version: "stable", + optimize: "0", + code: text, + edition: edition + }; + + if (text.indexOf("#![feature") !== -1) { + params.version = "nightly"; + } + + result_block.innerText = "Running..."; + + fetch_with_timeout("https://play.rust-lang.org/evaluate.json", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + body: JSON.stringify(params) + }) + .then(response => response.json()) + .then(response => { + if (response.result.trim() === '') { + result_block.innerText = "No output"; + result_block.classList.add("result-no-output"); + } else { + result_block.innerText = response.result; + result_block.classList.remove("result-no-output"); + } + }) + .catch(error => result_block.innerText = "Playground Communication: " + error.message); + } + + // Syntax highlighting Configuration + hljs.configure({ + tabReplace: ' ', // 4 spaces + languages: [], // Languages used for auto-detection + }); + + let code_nodes = Array + .from(document.querySelectorAll('code')) + // Don't highlight `inline code` blocks in headers. + .filter(function (node) {return !node.parentElement.classList.contains("header"); }); + + if (window.ace) { + // language-rust class needs to be removed for editable + // blocks or highlightjs will capture events + code_nodes + .filter(function (node) {return node.classList.contains("editable"); }) + .forEach(function (block) { block.classList.remove('language-rust'); }); + + code_nodes + .filter(function (node) {return !node.classList.contains("editable"); }) + .forEach(function (block) { hljs.highlightBlock(block); }); + } else { + code_nodes.forEach(function (block) { hljs.highlightBlock(block); }); + } + + // Adding the hljs class gives code blocks the color css + // even if highlighting doesn't apply + code_nodes.forEach(function (block) { block.classList.add('hljs'); }); + + Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) { + + var lines = Array.from(block.querySelectorAll('.boring')); + // If no lines were hidden, return + if (!lines.length) { return; } + block.classList.add("hide-boring"); + + var buttons = document.createElement('div'); + buttons.className = 'buttons'; + buttons.innerHTML = ""; + + // add expand button + var pre_block = block.parentNode; + pre_block.insertBefore(buttons, pre_block.firstChild); + + pre_block.querySelector('.buttons').addEventListener('click', function (e) { + if (e.target.classList.contains('fa-eye')) { + e.target.classList.remove('fa-eye'); + e.target.classList.add('fa-eye-slash'); + e.target.title = 'Hide lines'; + e.target.setAttribute('aria-label', e.target.title); + + block.classList.remove('hide-boring'); + } else if (e.target.classList.contains('fa-eye-slash')) { + e.target.classList.remove('fa-eye-slash'); + e.target.classList.add('fa-eye'); + e.target.title = 'Show hidden lines'; + e.target.setAttribute('aria-label', e.target.title); + + block.classList.add('hide-boring'); + } + }); + }); + + if (window.playground_copyable) { + Array.from(document.querySelectorAll('pre code')).forEach(function (block) { + var pre_block = block.parentNode; + if (!pre_block.classList.contains('playground')) { + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var clipButton = document.createElement('button'); + clipButton.className = 'clip-button'; + clipButton.title = 'Copy to clipboard'; + clipButton.setAttribute('aria-label', clipButton.title); + clipButton.innerHTML = ''; + + buttons.insertBefore(clipButton, buttons.firstChild); + } + }); + } + + // Process playground code blocks + Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) { + // Add play button + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var runCodeButton = document.createElement('button'); + runCodeButton.className = 'fa fa-play play-button'; + runCodeButton.hidden = true; + runCodeButton.title = 'Run this code'; + runCodeButton.setAttribute('aria-label', runCodeButton.title); + + buttons.insertBefore(runCodeButton, buttons.firstChild); + runCodeButton.addEventListener('click', function (e) { + run_rust_code(pre_block); + }); + + if (window.playground_copyable) { + var copyCodeClipboardButton = document.createElement('button'); + copyCodeClipboardButton.className = 'clip-button'; + copyCodeClipboardButton.innerHTML = ''; + copyCodeClipboardButton.title = 'Copy to clipboard'; + copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title); + + buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild); + } + + let code_block = pre_block.querySelector("code"); + if (window.ace && code_block.classList.contains("editable")) { + var undoChangesButton = document.createElement('button'); + undoChangesButton.className = 'fa fa-history reset-button'; + undoChangesButton.title = 'Undo changes'; + undoChangesButton.setAttribute('aria-label', undoChangesButton.title); + + buttons.insertBefore(undoChangesButton, buttons.firstChild); + + undoChangesButton.addEventListener('click', function () { + let editor = window.ace.edit(code_block); + editor.setValue(editor.originalCode); + editor.clearSelection(); + }); + } + }); +})(); + +(function themes() { + var html = document.querySelector('html'); + var themeToggleButton = document.getElementById('theme-toggle'); + var themePopup = document.getElementById('theme-list'); + var themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); + var themeIds = []; + themePopup.querySelectorAll('button.theme').forEach(function (el) { + themeIds.push(el.id); + }); + var stylesheets = { + ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"), + tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"), + highlight: document.querySelector("[href$='highlight.css']"), + }; + + function showThemes() { + themePopup.style.display = 'block'; + themeToggleButton.setAttribute('aria-expanded', true); + themePopup.querySelector("button#" + get_theme()).focus(); + } + + function updateThemeSelected() { + themePopup.querySelectorAll('.theme-selected').forEach(function (el) { + el.classList.remove('theme-selected'); + }); + themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected'); + } + + function hideThemes() { + themePopup.style.display = 'none'; + themeToggleButton.setAttribute('aria-expanded', false); + themeToggleButton.focus(); + } + + function get_theme() { + var theme; + try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { } + if (theme === null || theme === undefined || !themeIds.includes(theme)) { + return default_theme; + } else { + return theme; + } + } + + function set_theme(theme, store = true) { + let ace_theme; + + if (theme == 'coal' || theme == 'navy') { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = false; + stylesheets.highlight.disabled = true; + + ace_theme = "ace/theme/tomorrow_night"; + } else if (theme == 'ayu') { + stylesheets.ayuHighlight.disabled = false; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = true; + ace_theme = "ace/theme/tomorrow_night"; + } else { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = false; + ace_theme = "ace/theme/dawn"; + } + + setTimeout(function () { + themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor; + }, 1); + + if (window.ace && window.editors) { + window.editors.forEach(function (editor) { + editor.setTheme(ace_theme); + }); + } + + var previousTheme = get_theme(); + + if (store) { + try { localStorage.setItem('mdbook-theme', theme); } catch (e) { } + } + + html.classList.remove(previousTheme); + html.classList.add(theme); + updateThemeSelected(); + } + + // Set theme + var theme = get_theme(); + + set_theme(theme, false); + + themeToggleButton.addEventListener('click', function () { + if (themePopup.style.display === 'block') { + hideThemes(); + } else { + showThemes(); + } + }); + + themePopup.addEventListener('click', function (e) { + var theme; + if (e.target.className === "theme") { + theme = e.target.id; + } else if (e.target.parentElement.className === "theme") { + theme = e.target.parentElement.id; + } else { + return; + } + set_theme(theme); + }); + + themePopup.addEventListener('focusout', function(e) { + // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below) + if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) { + hideThemes(); + } + }); + + // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628 + document.addEventListener('click', function(e) { + if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) { + hideThemes(); + } + }); + + document.addEventListener('keydown', function (e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } + if (!themePopup.contains(e.target)) { return; } + + switch (e.key) { + case 'Escape': + e.preventDefault(); + hideThemes(); + break; + case 'ArrowUp': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.previousElementSibling) { + li.previousElementSibling.querySelector('button').focus(); + } + break; + case 'ArrowDown': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.nextElementSibling) { + li.nextElementSibling.querySelector('button').focus(); + } + break; + case 'Home': + e.preventDefault(); + themePopup.querySelector('li:first-child button').focus(); + break; + case 'End': + e.preventDefault(); + themePopup.querySelector('li:last-child button').focus(); + break; } }); })(); (function sidebar() { - var html = document.querySelector("html"); + var body = document.querySelector("body"); var sidebar = document.getElementById("sidebar"); var sidebarLinks = document.querySelectorAll('#sidebar a'); var sidebarToggleButton = document.getElementById("sidebar-toggle"); + var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); var firstContact = null; function showSidebar() { - html.classList.remove('sidebar-hidden') - html.classList.add('sidebar-visible'); + body.classList.remove('sidebar-hidden') + body.classList.add('sidebar-visible'); Array.from(sidebarLinks).forEach(function (link) { link.setAttribute('tabIndex', 0); }); @@ -37,8 +464,8 @@ window.onunload = function () { }; } function hideSidebar() { - html.classList.remove('sidebar-visible') - html.classList.add('sidebar-hidden'); + body.classList.remove('sidebar-visible') + body.classList.add('sidebar-hidden'); Array.from(sidebarLinks).forEach(function (link) { link.setAttribute('tabIndex', -1); }); @@ -49,9 +476,14 @@ window.onunload = function () { }; // Toggle sidebar sidebarToggleButton.addEventListener('click', function sidebarToggle() { - if (html.classList.contains("sidebar-hidden")) { + if (body.classList.contains("sidebar-hidden")) { + var current_width = parseInt( + document.documentElement.style.getPropertyValue('--sidebar-width'), 10); + if (current_width < 150) { + document.documentElement.style.setProperty('--sidebar-width', '150px'); + } showSidebar(); - } else if (html.classList.contains("sidebar-visible")) { + } else if (body.classList.contains("sidebar-visible")) { hideSidebar(); } else { if (getComputedStyle(sidebar)['transform'] === 'none') { @@ -62,6 +494,32 @@ window.onunload = function () { }; } }); + sidebarResizeHandle.addEventListener('mousedown', initResize, false); + + function initResize(e) { + window.addEventListener('mousemove', resize, false); + window.addEventListener('mouseup', stopResize, false); + body.classList.add('sidebar-resizing'); + } + function resize(e) { + var pos = (e.clientX - sidebar.offsetLeft); + if (pos < 20) { + hideSidebar(); + } else { + if (body.classList.contains("sidebar-hidden")) { + showSidebar(); + } + pos = Math.min(pos, window.innerWidth - 100); + document.documentElement.style.setProperty('--sidebar-width', pos + 'px'); + } + } + //on mouseup remove windows functions mousemove & mouseup + function stopResize(e) { + body.classList.remove('sidebar-resizing'); + window.removeEventListener('mousemove', resize, false); + window.removeEventListener('mouseup', stopResize, false); + } + document.addEventListener('touchstart', function (e) { firstContact = { x: e.touches[0].clientX, @@ -86,34 +544,147 @@ window.onunload = function () { }; firstContact = null; } }, { passive: true }); - - // Scroll sidebar to current active section - var activeSection = sidebar.querySelector(".active"); - if (activeSection) { - sidebar.scrollTop = activeSection.offsetTop; - } })(); (function chapterNavigation() { document.addEventListener('keydown', function (e) { if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } if (window.search && window.search.hasFocus()) { return; } + var html = document.querySelector('html'); + function next() { + var nextButton = document.querySelector('.nav-chapters.next'); + if (nextButton) { + window.location.href = nextButton.href; + } + } + function prev() { + var previousButton = document.querySelector('.nav-chapters.previous'); + if (previousButton) { + window.location.href = previousButton.href; + } + } switch (e.key) { case 'ArrowRight': e.preventDefault(); - var nextButton = document.querySelector('.nav-chapters.next'); - if (nextButton) { - window.location.href = nextButton.href; + if (html.dir == 'rtl') { + prev(); + } else { + next(); } break; case 'ArrowLeft': e.preventDefault(); - var previousButton = document.querySelector('.nav-chapters.previous'); - if (previousButton) { - window.location.href = previousButton.href; + if (html.dir == 'rtl') { + next(); + } else { + prev(); } break; } }); })(); + +(function clipboard() { + var clipButtons = document.querySelectorAll('.clip-button'); + + function hideTooltip(elem) { + elem.firstChild.innerText = ""; + elem.className = 'clip-button'; + } + + function showTooltip(elem, msg) { + elem.firstChild.innerText = msg; + elem.className = 'clip-button tooltipped'; + } + + var clipboardSnippets = new ClipboardJS('.clip-button', { + text: function (trigger) { + hideTooltip(trigger); + let playground = trigger.closest("pre"); + return playground_text(playground, false); + } + }); + + Array.from(clipButtons).forEach(function (clipButton) { + clipButton.addEventListener('mouseout', function (e) { + hideTooltip(e.currentTarget); + }); + }); + + clipboardSnippets.on('success', function (e) { + e.clearSelection(); + showTooltip(e.trigger, "Copied!"); + }); + + clipboardSnippets.on('error', function (e) { + showTooltip(e.trigger, "Clipboard error!"); + }); +})(); + +(function scrollToTop () { + var menuTitle = document.querySelector('.menu-title'); + + menuTitle.addEventListener('click', function () { + document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' }); + }); +})(); + +(function controllMenu() { + var menu = document.getElementById('menu-bar'); + + (function controllPosition() { + var scrollTop = document.scrollingElement.scrollTop; + var prevScrollTop = scrollTop; + var minMenuY = -menu.clientHeight - 50; + // When the script loads, the page can be at any scroll (e.g. if you reforesh it). + menu.style.top = scrollTop + 'px'; + // Same as parseInt(menu.style.top.slice(0, -2), but faster + var topCache = menu.style.top.slice(0, -2); + menu.classList.remove('sticky'); + var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster + document.addEventListener('scroll', function () { + scrollTop = Math.max(document.scrollingElement.scrollTop, 0); + // `null` means that it doesn't need to be updated + var nextSticky = null; + var nextTop = null; + var scrollDown = scrollTop > prevScrollTop; + var menuPosAbsoluteY = topCache - scrollTop; + if (scrollDown) { + nextSticky = false; + if (menuPosAbsoluteY > 0) { + nextTop = prevScrollTop; + } + } else { + if (menuPosAbsoluteY > 0) { + nextSticky = true; + } else if (menuPosAbsoluteY < minMenuY) { + nextTop = prevScrollTop + minMenuY; + } + } + if (nextSticky === true && stickyCache === false) { + menu.classList.add('sticky'); + stickyCache = true; + } else if (nextSticky === false && stickyCache === true) { + menu.classList.remove('sticky'); + stickyCache = false; + } + if (nextTop !== null) { + menu.style.top = nextTop + 'px'; + topCache = nextTop; + } + prevScrollTop = scrollTop; + }, { passive: true }); + })(); + (function controllBorder() { + function updateBorder() { + if (menu.offsetTop === 0) { + menu.classList.remove('bordered'); + } else { + menu.classList.add('bordered'); + } + } + updateBorder(); + document.addEventListener('scroll', updateBorder, { passive: true }); + })(); +})(); diff --git a/src/theme/css/chrome.css b/src/theme/css/chrome.css index 544e7718e..4cd73086d 100644 --- a/src/theme/css/chrome.css +++ b/src/theme/css/chrome.css @@ -1,109 +1,114 @@ /* CSS for UI elements (a.k.a. chrome) */ -@import 'variables.css'; - -::-webkit-scrollbar { - background: var(--bg); -} -::-webkit-scrollbar-thumb { - background: var(--scrollbar); -} html { - scrollbar-color: var(--scrollbar) var(--bg); + scrollbar-color: var(--scrollbar) var(--bg); } #searchresults a, .content a:link, a:visited, a > .hljs { - color: var(--links); + color: var(--links); +} + +/* + body-container is necessary because mobile browsers don't seem to like + overflow-x on the body tag when there is a tag. +*/ +#body-container { + /* + This is used when the sidebar pushes the body content off the side of + the screen on small screens. Without it, dragging on mobile Safari + will want to reposition the viewport in a weird way. + */ + overflow-x: clip; } /* Menu Bar */ #menu-bar, #menu-bar-hover-placeholder { - z-index: 101; - margin: auto calc(0px - var(--page-padding)); + z-index: 101; + margin: auto calc(0px - var(--page-padding)); } #menu-bar { - position: relative; - display: flex; - flex-wrap: wrap; - background-color: var(--bg); - border-bottom-color: var(--bg); - border-bottom-width: 1px; - border-bottom-style: solid; + position: relative; + display: flex; + flex-wrap: wrap; + background-color: var(--bg); + border-block-end-color: var(--bg); + border-block-end-width: 1px; + border-block-end-style: solid; } #menu-bar.sticky, -.js #menu-bar-hover-placeholder:hover + #menu-bar, -.js #menu-bar:hover, -.js.sidebar-visible #menu-bar { - position: -webkit-sticky; - position: sticky; - top: 0 !important; +#menu-bar-hover-placeholder:hover + #menu-bar, +#menu-bar:hover, +html.sidebar-visible #menu-bar { + position: -webkit-sticky; + position: sticky; + top: 0 !important; } #menu-bar-hover-placeholder { - position: sticky; - position: -webkit-sticky; - top: 0; - height: var(--menu-bar-height); + position: sticky; + position: -webkit-sticky; + top: 0; + height: var(--menu-bar-height); } #menu-bar.bordered { - border-bottom-color: var(--table-border-color); + border-block-end-color: var(--table-border-color); } #menu-bar i, #menu-bar .icon-button { - position: relative; - padding: 0 8px; - z-index: 10; - line-height: var(--menu-bar-height); - cursor: pointer; - transition: color 0.5s; + position: relative; + padding: 0 8px; + z-index: 10; + line-height: var(--menu-bar-height); + cursor: pointer; + transition: color 0.5s; } @media only screen and (max-width: 420px) { - #menu-bar i, #menu-bar .icon-button { - padding: 0 5px; - } + #menu-bar i, #menu-bar .icon-button { + padding: 0 5px; + } } .icon-button { - border: none; - background: none; - padding: 0; - color: inherit; + border: none; + background: none; + padding: 0; + color: inherit; } .icon-button i { - margin: 0; + margin: 0; } .right-buttons { - margin: 0 15px; + margin: 0 15px; } .right-buttons a { - text-decoration: none; + text-decoration: none; } .left-buttons { - display: flex; - margin: 0 5px; + display: flex; + margin: 0 5px; } -.no-js .left-buttons { - display: none; +html:not(.js) .left-buttons button { + display: none; } .menu-title { - display: inline-block; - font-weight: 200; - font-size: 2.4rem; - line-height: var(--menu-bar-height); - text-align: center; - margin: 0; - flex: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + display: inline-block; + font-weight: 200; + font-size: 2.4rem; + line-height: var(--menu-bar-height); + text-align: center; + margin: 0; + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } -.js .menu-title { - cursor: pointer; +.menu-title { + cursor: pointer; } .menu-bar, @@ -114,371 +119,522 @@ a > .hljs { .mobile-nav-chapters:visited, .menu-bar .icon-button, .menu-bar a i { - color: var(--icons); + color: var(--icons); } .menu-bar i:hover, .menu-bar .icon-button:hover, .nav-chapters:hover, .mobile-nav-chapters i:hover { - color: var(--icons-hover); + color: var(--icons-hover); } /* Nav Icons */ .nav-chapters { - font-size: 2.5em; - text-align: center; - text-decoration: none; + font-size: 2.5em; + text-align: center; + text-decoration: none; - position: fixed; - top: 0; - bottom: 0; - margin: 0; - max-width: 150px; - min-width: 90px; + position: fixed; + top: 0; + bottom: 0; + margin: 0; + max-width: 150px; + min-width: 90px; - display: flex; - justify-content: center; - align-content: center; - flex-direction: column; + display: flex; + justify-content: center; + align-content: center; + flex-direction: column; - transition: color 0.5s, background-color 0.5s; + transition: color 0.5s, background-color 0.5s; } .nav-chapters:hover { - text-decoration: none; - transition: color 0.15s, color 0.15s; + text-decoration: none; + background-color: var(--theme-hover); + transition: background-color 0.15s, color 0.15s; } .nav-wrapper { - margin-top: 50px; - display: none; + margin-block-start: 50px; + display: none; } .mobile-nav-chapters { - font-size: 2.5em; - text-align: center; - text-decoration: none; - width: 90px; - border-radius: 5px; - background-color: var(--sidebar-bg); + font-size: 2.5em; + text-align: center; + text-decoration: none; + width: 90px; + border-radius: 5px; + background-color: var(--sidebar-bg); } -.previous { - float: left; -} +/* Only Firefox supports flow-relative values */ +.previous { float: left; } +[dir=rtl] .previous { float: right; } +/* Only Firefox supports flow-relative values */ .next { - float: right; - right: var(--page-padding); + float: right; + right: var(--page-padding); } +[dir=rtl] .next { + float: left; + right: unset; + left: var(--page-padding); +} + +/* Use the correct buttons for RTL layouts*/ +[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";} +[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; } @media only screen and (max-width: 1080px) { - .nav-wide-wrapper { display: none; } - .nav-wrapper { display: block; } + .nav-wide-wrapper { display: none; } + .nav-wrapper { display: block; } } +/* sidebar-visible */ @media only screen and (max-width: 1380px) { - .sidebar-visible .nav-wide-wrapper { display: none; } - .sidebar-visible .nav-wrapper { display: block; } + #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper { display: none; } + #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper { display: block; } } /* Inline code */ :not(pre) > .hljs { - display: inline; - padding: 0.1em 0.3em; - border-radius: 3px; + display: inline; + padding: 0.1em 0.3em; + border-radius: 3px; } :not(pre):not(a) > .hljs { - color: var(--inline-code-color); - overflow-x: initial; + color: var(--inline-code-color); + overflow-x: initial; } a:hover > .hljs { - text-decoration: underline; + text-decoration: underline; } pre { - position: relative; + position: relative; } pre > .buttons { - position: absolute; - z-index: 100; - right: 5px; - top: 5px; - - color: var(--sidebar-fg); - cursor: pointer; + position: absolute; + z-index: 100; + right: 0px; + top: 2px; + margin: 0px; + padding: 2px 0px; + + color: var(--sidebar-fg); + cursor: pointer; + visibility: hidden; + opacity: 0; + transition: visibility 0.1s linear, opacity 0.1s linear; +} +pre:hover > .buttons { + visibility: visible; + opacity: 1 } pre > .buttons :hover { - color: var(--sidebar-active); + color: var(--sidebar-active); + border-color: var(--icons-hover); + background-color: var(--theme-hover); } pre > .buttons i { - margin-left: 8px; + margin-inline-start: 8px; } pre > .buttons button { - color: inherit; - background: transparent; - border: none; - cursor: inherit; + cursor: inherit; + margin: 0px 5px; + padding: 4px 4px 3px 5px; + font-size: 23px; + + border-style: solid; + border-width: 1px; + border-radius: 4px; + border-color: var(--icons); + background-color: var(--theme-popup-bg); + transition: 100ms; + transition-property: color,border-color,background-color; + color: var(--icons); +} + +pre > .buttons button.clip-button { + padding: 2px 4px 0px 6px; +} +pre > .buttons button.clip-button::before { + /* clipboard image from octicons (https://github.com/primer/octicons/tree/v2.0.0) MIT license + */ + content: url('data:image/svg+xml,\ +\ +\ +'); + filter: var(--copy-button-filter); +} +pre > .buttons button.clip-button:hover::before { + filter: var(--copy-button-filter-hover); +} + +@media (pointer: coarse) { + pre > .buttons button { + /* On mobile, make it easier to tap buttons. */ + padding: 0.3rem 1rem; + } + + .sidebar-resize-indicator { + /* Hide resize indicator on devices with limited accuracy */ + display: none; + } +} +pre > code { + display: block; + padding: 1rem; +} + +/* FIXME: ACE editors overlap their buttons because ACE does absolute + positioning within the code block which breaks padding. The only solution I + can think of is to move the padding to the outer pre tag (or insert a div + wrapper), but that would require fixing a whole bunch of CSS rules. +*/ +.hljs.ace_editor { + padding: 0rem 0rem; } + pre > .result { - margin-top: 10px; + margin-block-start: 10px; } /* Search */ #searchresults a { - text-decoration: none; + text-decoration: none; } mark { - border-radius: 2px; - padding: 0 3px 1px 3px; - margin: 0 -3px -1px -3px; - background-color: var(--search-mark-bg); - transition: background-color 300ms linear; - cursor: pointer; + border-radius: 2px; + padding-block-start: 0; + padding-block-end: 1px; + padding-inline-start: 3px; + padding-inline-end: 3px; + margin-block-start: 0; + margin-block-end: -1px; + margin-inline-start: -3px; + margin-inline-end: -3px; + background-color: var(--search-mark-bg); + transition: background-color 300ms linear; + cursor: pointer; } mark.fade-out { - background-color: rgba(0,0,0,0) !important; - cursor: auto; + background-color: rgba(0,0,0,0) !important; + cursor: auto; } .searchbar-outer { - margin-left: auto; - margin-right: auto; - max-width: var(--content-max-width); + margin-inline-start: auto; + margin-inline-end: auto; + max-width: var(--content-max-width); } #searchbar { - width: 100%; - margin: 5px auto 0px auto; - padding: 10px 16px; - transition: box-shadow 300ms ease-in-out; - border: 1px solid var(--searchbar-border-color); - border-radius: 3px; - background-color: var(--searchbar-bg); - color: var(--searchbar-fg); + width: 100%; + margin-block-start: 5px; + margin-block-end: 0; + margin-inline-start: auto; + margin-inline-end: auto; + padding: 10px 16px; + transition: box-shadow 300ms ease-in-out; + border: 1px solid var(--searchbar-border-color); + border-radius: 3px; + background-color: var(--searchbar-bg); + color: var(--searchbar-fg); } #searchbar:focus, #searchbar.active { - box-shadow: 0 0 3px var(--searchbar-shadow-color); + box-shadow: 0 0 3px var(--searchbar-shadow-color); } .searchresults-header { - font-weight: bold; - font-size: 1em; - padding: 18px 0 0 5px; - color: var(--searchresults-header-fg); + font-weight: bold; + font-size: 1em; + padding-block-start: 18px; + padding-block-end: 0; + padding-inline-start: 5px; + padding-inline-end: 0; + color: var(--searchresults-header-fg); } .searchresults-outer { - margin-left: auto; - margin-right: auto; - max-width: var(--content-max-width); - border-bottom: 1px dashed var(--searchresults-border-color); + margin-inline-start: auto; + margin-inline-end: auto; + max-width: var(--content-max-width); + border-block-end: 1px dashed var(--searchresults-border-color); } ul#searchresults { - list-style: none; - padding-left: 20px; + list-style: none; + padding-inline-start: 20px; } ul#searchresults li { - margin: 10px 0px; - padding: 2px; - border-radius: 2px; + margin: 10px 0px; + padding: 2px; + border-radius: 2px; } ul#searchresults li.focus { - background-color: var(--searchresults-li-bg); + background-color: var(--searchresults-li-bg); } ul#searchresults span.teaser { - display: block; - clear: both; - margin: 5px 0 0 20px; - font-size: 0.8em; + display: block; + clear: both; + margin-block-start: 5px; + margin-block-end: 0; + margin-inline-start: 20px; + margin-inline-end: 0; + font-size: 0.8em; } ul#searchresults span.teaser em { - font-weight: bold; - font-style: normal; + font-weight: bold; + font-style: normal; } /* Sidebar */ .sidebar { - position: fixed; - left: 0; - top: 0; - bottom: 0; - width: var(--sidebar-width); - font-size: 0.875em; - box-sizing: border-box; - -webkit-overflow-scrolling: touch; - overscroll-behavior-y: contain; - background-color: var(--sidebar-bg); - color: var(--sidebar-fg); -} + position: fixed; + left: 0; + top: 0; + bottom: 0; + width: var(--sidebar-width); + font-size: 0.875em; + box-sizing: border-box; + -webkit-overflow-scrolling: touch; + overscroll-behavior-y: contain; + background-color: var(--sidebar-bg); + color: var(--sidebar-fg); +} +.sidebar-iframe-inner { + background-color: var(--sidebar-bg); + color: var(--sidebar-fg); + padding: 10px 10px; + margin: 0; + font-size: 1.4rem; +} +.sidebar-iframe-outer { + border: none; + height: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} +[dir=rtl] .sidebar { left: unset; right: 0; } .sidebar-resizing { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; } -.js:not(.sidebar-resizing) .sidebar { - transition: transform 0.3s; /* Animation: slide away */ +html:not(.sidebar-resizing) .sidebar { + transition: transform 0.3s; /* Animation: slide away */ } .sidebar code { - line-height: 2em; -} -/* .sidebar .sidebar-scrollbox { - overflow-y: auto; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - padding: 10px 10px; -} */ + line-height: 2em; +} +.sidebar .sidebar-scrollbox { + overflow-y: auto; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + padding: 10px 10px; +} .sidebar .sidebar-resize-handle { - position: absolute; - cursor: col-resize; - width: 0; - right: 0; - top: 0; - bottom: 0; + position: absolute; + cursor: col-resize; + width: 0; + right: calc(var(--sidebar-resize-indicator-width) * -1); + top: 0; + bottom: 0; + display: flex; + align-items: center; +} + +.sidebar-resize-handle .sidebar-resize-indicator { + width: 100%; + height: 12px; + background-color: var(--icons); + margin-inline-start: var(--sidebar-resize-indicator-space); +} + +[dir=rtl] .sidebar .sidebar-resize-handle { + left: calc(var(--sidebar-resize-indicator-width) * -1); + right: unset; } .js .sidebar .sidebar-resize-handle { - cursor: col-resize; - width: 5px; + cursor: col-resize; + width: calc(var(--sidebar-resize-indicator-width) - var(--sidebar-resize-indicator-space)); +} +/* sidebar-hidden */ +#sidebar-toggle-anchor:not(:checked) ~ .sidebar { + transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width))); + z-index: -1; } -.sidebar-hidden .sidebar { - transform: translateX(calc(0px - var(--sidebar-width))); +[dir=rtl] #sidebar-toggle-anchor:not(:checked) ~ .sidebar { + transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width))); } .sidebar::-webkit-scrollbar { - background: var(--sidebar-bg); + background: var(--sidebar-bg); } .sidebar::-webkit-scrollbar-thumb { - background: var(--scrollbar); + background: var(--scrollbar); +} + +/* sidebar-visible */ +#sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width))); +} +[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width))); +} +@media only screen and (min-width: 620px) { + #sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: none; + margin-inline-start: calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)); + } + [dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: none; + } } .chapter { - list-style: none outside none; - padding-left: 0; - line-height: 2.2em; + list-style: none outside none; + padding-inline-start: 0; + line-height: 2.2em; } .chapter ol { - width: 100%; + width: 100%; } .chapter li { - display: flex; - color: var(--sidebar-non-existant); + display: flex; + color: var(--sidebar-non-existant); } .chapter li a { - display: block; - padding: 0; - text-decoration: none; - color: var(--sidebar-fg); + display: block; + padding: 0; + text-decoration: none; + color: var(--sidebar-fg); } .chapter li a:hover { - color: var(--sidebar-active); + color: var(--sidebar-active); } .chapter li a.active { - color: var(--sidebar-active); + color: var(--sidebar-active); } .chapter li > a.toggle { - cursor: pointer; - display: block; - margin-left: auto; - padding: 0 10px; - user-select: none; - opacity: 0.68; + cursor: pointer; + display: block; + margin-inline-start: auto; + padding: 0 10px; + user-select: none; + opacity: 0.68; } .chapter li > a.toggle div { - transition: transform 0.5s; + transition: transform 0.5s; } /* collapse the section */ .chapter li:not(.expanded) + li > ol { - display: none; + display: none; } .chapter li.chapter-item { - line-height: 1.5em; - margin-top: 0.6em; + line-height: 1.5em; + margin-block-start: 0.6em; } .chapter li.expanded > a.toggle div { - transform: rotate(90deg); + transform: rotate(90deg); } .spacer { - width: 100%; - height: 3px; - margin: 5px 0px; + width: 100%; + height: 3px; + margin: 5px 0px; } .chapter .spacer { - background-color: var(--sidebar-spacer); + background-color: var(--sidebar-spacer); } @media (-moz-touch-enabled: 1), (pointer: coarse) { - .chapter li a { padding: 5px 0; } - .spacer { margin: 10px 0; } + .chapter li a { padding: 5px 0; } + .spacer { margin: 10px 0; } } .section { - list-style: none outside none; - padding-left: 20px; - line-height: 1.9em; + list-style: none outside none; + padding-inline-start: 20px; + line-height: 1.9em; } /* Theme Menu Popup */ .theme-popup { - position: absolute; - left: 10px; - top: var(--menu-bar-height); - z-index: 1000; - border-radius: 4px; - font-size: 0.7em; - color: var(--fg); - background: var(--theme-popup-bg); - border: 1px solid var(--theme-popup-border); - margin: 0; - padding: 0; - list-style: none; - display: none; -} + position: absolute; + left: 10px; + top: var(--menu-bar-height); + z-index: 1000; + border-radius: 4px; + font-size: 0.7em; + color: var(--fg); + background: var(--theme-popup-bg); + border: 1px solid var(--theme-popup-border); + margin: 0; + padding: 0; + list-style: none; + display: none; + /* Don't let the children's background extend past the rounded corners. */ + overflow: hidden; +} +[dir=rtl] .theme-popup { left: unset; right: 10px; } .theme-popup .default { - color: var(--icons); + color: var(--icons); } .theme-popup .theme { - width: 100%; - border: 0; - margin: 0; - padding: 2px 10px; - line-height: 25px; - white-space: nowrap; - text-align: left; - cursor: pointer; - color: inherit; - background: inherit; - font-size: inherit; + width: 100%; + border: 0; + margin: 0; + padding: 2px 20px; + line-height: 25px; + white-space: nowrap; + text-align: start; + cursor: pointer; + color: inherit; + background: inherit; + font-size: inherit; } .theme-popup .theme:hover { - background-color: var(--theme-hover); + background-color: var(--theme-hover); } -.theme-popup .theme:hover:first-child, -.theme-popup .theme:hover:last-child { - border-top-left-radius: inherit; - border-top-right-radius: inherit; + +.theme-selected::before { + display: inline-block; + content: "✓"; + margin-inline-start: -14px; + width: 14px; } diff --git a/src/theme/css/general.css b/src/theme/css/general.css index 4eb45e393..0862b5167 100644 --- a/src/theme/css/general.css +++ b/src/theme/css/general.css @@ -1,351 +1,242 @@ -@import 'variables.css'; +/* Base styles and content styles */ -body { - font-family: 'Ubuntu', sans-serif; - font-size: 1rem; - line-height: 1.5; - color: var(--fg); - margin: 0; - background-color: var(--bg); -} -h1, h2, h3, h4, h5, h6 { color: var(--fg); } -a, a:visited { - color: var(--links); - text-decoration: none; -} -a:hover, a:visited:hover { - color: var(--links-hover); - text-decoration: underline; -} - -code { - background: var(--inline-code-color); - padding: 2px 4px; - border-radius: 4px; - white-space: pre-wrap; - overflow-wrap: break-word; -} -pre code { - padding: 0; - border-radius: 0; -} -pre { - padding: .5em; - margin: 1em 0; - background: var(--inline-code-color); - border: 1px solid var(--code-border); - border-radius: 4px; -} - -blockquote { - margin: 20px 0; - padding: 0 20px; - padding-left: 1em; - background: var(--quote-bg); - border: 1px solid var(--quote-border); - border-left: none; - border-right: none; +:root { + /* Browser default font-size is 16px, this way 1 rem = 10px */ + font-size: 62.5%; + color-scheme: var(--color-scheme); } -blockquote code { - background: var(--quote-code-bg); +html { + font-family: "Open Sans", sans-serif; + color: var(--fg); + background-color: var(--bg); + text-size-adjust: none; + -webkit-text-size-adjust: none; } -li.js-unavailable { - background-color: #f6cf68; - border-radius: 10px; - margin-left: 1em; - padding-left: 1em; - padding-right: 1em; +body { + margin: 0; + font-size: 1.6rem; + overflow-x: hidden; } -table { - border-collapse: collapse; - display: block; - overflow-y: auto; - border: 1px var(--table-border-color) solid; -} -table td { - padding: 3px 20px; -} -table thead { - background: var(--table-header-bg); - color: var(--table-header-fg); -} -table thead td { - font-weight: 700; -} -table tbody tr:nth-child(2n) { - /* Alternate background colors for rows */ - background: var(--table-alternate-bg); +code { + font-family: var(--mono-font) !important; + font-size: var(--code-font-size); + direction: ltr !important; } -svg { - position: relative; - top: .125em; - width: 1em; - height: auto; +/* make long words/inline code not x overflow */ +main { + overflow-wrap: break-word; } -.hidden { - display: none; +/* make wide tables scroll if they overflow */ +.table-wrapper { + overflow-x: auto; } -.icon-button { - border: none; - background: none; - cursor: pointer; - padding: 1em; +/* Don't change font size in headers. */ +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + font-size: unset; } -/* void navigation */ +.left { float: left; } +.right { float: right; } +.boring { opacity: 0.6; } +.hide-boring .boring { display: none; } +.hidden { display: none !important; } -#void-nav { - width: 100%; - min-height: 50px; - background: var(--nav-bg); - font-size: 14px; +h2, h3 { margin-block-start: 2.5em; } +h4, h5 { margin-block-start: 2em; } - display: flex; - flex-direction: row; - flex-wrap: wrap; -} -#void-nav a, -#void-nav button, -#void-nav label { - fill: var(--nav-fg); - height: 50px; - min-height: 100%; - display: block; - line-height: 50px; - padding: 0 15px; - font-size: 1.2em; -} -#void-nav ul { - list-style: none; - margin: 0; - padding: 0; +.header + .header h3, +.header + .header h4, +.header + .header h5 { + margin-block-start: 1em; } -#void-nav ul#nav-right { - margin-left: auto; +h1:target::before, +h2:target::before, +h3:target::before, +h4:target::before, +h5:target::before, +h6:target::before { + display: inline-block; + content: "»"; + margin-inline-start: -30px; + width: 30px; } -#void-nav ul li { - display: inline-block; -} -#void-nav ul li a { - color: var(--nav-fg); - display: block; - padding: 0 15px; - line-height: 50px; - font-size: 1.2em; - text-decoration: none -} -#void-nav ul li a:hover, -#void-nav ul li a:focus, -#void-nav button:hover, -#void-nav button:focus, -#void-nav label:hover, -#void-nav label:focus { - background: #000; +/* This is broken on Safari as of version 14, but is fixed + in Safari Technology Preview 117 which I think will be Safari 14.2. + https://bugs.webkit.org/show_bug.cgi?id=218076 +*/ +:target { + /* Safari does not support logical properties */ + scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); } -#skip-to-content { - position: absolute; - left: -999px; - top: -999px; +.page { + outline: 0; + padding: 0 var(--page-padding); + margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ } - -#skip-to-content:active, -#skip-to-content:focus { - position: relative; - left: 0; - top: 0; +.page-wrapper { + box-sizing: border-box; + background-color: var(--bg); } - -#icon-theme-light { - display: var(--theme-toggle-light); +.no-js .page-wrapper, +.js:not(.sidebar-resizing) .page-wrapper { + transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ } -#icon-theme-dark { - display: var(--theme-toggle-dark); +[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper { + transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */ } -/* sidebar */ - -.sidebar-hidden #sidebar { - display: none; -} -#sidebar { - padding: .5em; - background: var(--sidebar-bg); - font-size: 0.875em; -} -#sidebar ol { - list-style: none; - margin: 0; +.content { + overflow-y: auto; + padding: 0 5px 50px 5px; } -#sidebar ol.chapter { - padding: 0; - line-height: 2.2em; +.content main { + margin-inline-start: auto; + margin-inline-end: auto; + max-width: var(--content-max-width); } -#sidebar ol.section { - padding-left: 20px; - line-height: 1.9em; +.content p { line-height: 1.45em; } +.content ol { line-height: 1.45em; } +.content ul { line-height: 1.45em; } +.content a { text-decoration: none; } +.content a:hover { text-decoration: underline; } +.content img, .content video { max-width: 100%; } +.content .header:link, +.content .header:visited { + color: var(--fg); } -#sidebar a { - color: var(--sidebar-fg); - display: block; -} -#sidebar a:hover { - color: var(--sidebar-active); - text-decoration: none; -} -#sidebar a.active { - display: block; - padding: 0.5em; - width: 100%; - background-color: var(--sidebar-active); - color: var(--bg); -} -#sidebar a.active::after { - content: "" / " selected"; -} - -#sidebar-toggle { - display: none; -} - -/* search */ - -#searchbar { - width: 100%; - padding: 10px 16px; - margin: 5px 0; - border-radius: 3px; - border: 1px solid var(--searchbar-border-color); -} -#searchresults-header { - font-weight: bold; - font-size: 1em; - padding: 18px 0 0 5px; -} -ul#searchresults { - list-style: none; - padding-left: 20px; -} -ul#searchresults li { - margin: 10px 0px; - padding: 2px; - border-radius: 2px; -} -ul#searchresults span.teaser { - display: block; - clear: both; - margin: 5px 0 0 20px; - font-size: 0.8em; -} - -/* chapter navigation */ - -#nav-wide-wrapper { - max-width: 800px; - margin: 0 auto; - margin-top: 50px; -} -.previous { - float: left; -} -.next { - float: right; - right: 15px; -} -.nav-chapters { - fill: var(--nav-arrow-fg); - text-align: center; - text-decoration: none; - display: block; - max-width: 150px; - min-width: 90px; -} -.nav-chapters:hover { - text-decoration: none; - fill: var(--nav-fg-hover); +.content .header:link, +.content .header:visited:hover { + text-decoration: none; } -.nav-chapters svg { - margin: 0 auto; - width: 1.5em; -} -.mobile-nav-chapters { - fill: var(--nav-arrow-fg); +table { + margin: 0 auto; + border-collapse: collapse; } -.mobile-nav-chapters:hover { - fill: var(--nav-fg-hover); +table td { + padding: 3px 20px; + border: 1px var(--table-border-color) solid; } - -/* layout */ - -body { - box-sizing: border-box; +table thead { + background: var(--table-header-bg); } -#content { - display: flex; - flex-direction: row; - width: 100%; +table thead td { + font-weight: 700; + border: none; } -#page-wrapper { - --content-padding: 10px; - padding: 0 var(--content-padding); - width: calc(100% - var(--content-padding) * 2); +table thead th { + padding: 3px 20px; } -#search-wrapper, -#page-wrapper main { - width: 100%; - max-width: 800px; - margin: 0 auto; +table thead tr { + border: 1px var(--table-header-bg) solid; } -#sidebar { - max-width: 300px; - flex-shrink: 0; +/* Alternate background colors for rows */ +table tbody tr:nth-child(2n) { + background: var(--table-alternate-bg); } -/* 300px + 800px + 2*90px + 15px */ -@media only screen and (min-width: 1295px) { - .sidebar-visible #nav-wide-wrapper { - max-width: none; - margin: 0; - } - .sidebar-visible .nav-chapters { - background: none; - position: fixed; - top: 50px; - bottom: 0; - margin: 0; - justify-content: center; - align-content: center; - display: flex; - flex-direction: column; - } -} -/* 800px + 2*90px + 15px */ -@media only screen and (min-width: 995px) { - .sidebar-hidden #nav-wide-wrapper { - max-width: none; - margin: 0; - } - .sidebar-hidden .nav-chapters { - background: none; - position: fixed; - top: 50px; - bottom: 0; - margin: 0; - justify-content: center; - align-content: center; - display: flex; - flex-direction: column; - } - table { - display: table; - } + +blockquote { + margin: 20px 0; + padding: 0 20px; + color: var(--fg); + background-color: var(--quote-bg); + border-block-start: .1em solid var(--quote-border); + border-block-end: .1em solid var(--quote-border); +} + +.warning { + margin: 20px; + padding: 0 20px; + border-inline-start: 2px solid var(--warning-border); +} + +.warning:before { + position: absolute; + width: 3rem; + height: 3rem; + margin-inline-start: calc(-1.5rem - 21px); + content: "ⓘ"; + text-align: center; + background-color: var(--bg); + color: var(--warning-border); + font-weight: bold; + font-size: 2rem; +} + +blockquote .warning:before { + background-color: var(--quote-bg); +} + +kbd { + background-color: var(--table-border-color); + border-radius: 4px; + border: solid 1px var(--theme-popup-border); + box-shadow: inset 0 -1px 0 var(--theme-hover); + display: inline-block; + font-size: var(--code-font-size); + font-family: var(--mono-font); + line-height: 10px; + padding: 4px 5px; + vertical-align: middle; +} + +sup { + /* Set the line-height for superscript and footnote references so that there + isn't an awkward space appearing above lines that contain the footnote. + + See https://github.com/rust-lang/mdBook/pull/2443#discussion_r1813773583 + for an explanation. + */ + line-height: 0; +} + +:not(.footnote-definition) + .footnote-definition, +.footnote-definition + :not(.footnote-definition) { + margin-block-start: 2em; +} +.footnote-definition { + font-size: 0.9em; + margin: 0.5em 0; +} +.footnote-definition p { + display: inline; +} + +.tooltiptext { + position: absolute; + visibility: hidden; + color: #fff; + background-color: #333; + transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */ + left: -8px; /* Half of the width of the icon */ + top: -35px; + font-size: 0.8em; + text-align: center; + border-radius: 6px; + padding: 5px 8px; + margin: 5px; + z-index: 1000; +} +.tooltipped .tooltiptext { + visibility: visible; +} + +.chapter li.part-title { + color: var(--sidebar-fg); + margin: 5px 0px; + font-weight: bold; +} + +.result-no-output { + font-style: italic; } diff --git a/src/theme/css/print.css b/src/theme/css/print.css index 2970c2b6c..80ec3a544 100644 --- a/src/theme/css/print.css +++ b/src/theme/css/print.css @@ -1,15 +1,14 @@ #sidebar, #menu-bar, -#void-nav, .nav-chapters, .mobile-nav-chapters { display: none; } #page-wrapper.page-wrapper { - transform: none; - margin-left: 0px; + transform: none !important; + margin-inline-start: 0px; overflow-y: initial; } @@ -24,19 +23,7 @@ } code { - background-color: #ddd; - border-radius: 5px; - - /* Force background to be printed in Chrome */ - -webkit-print-color-adjust: exact; -} - - -pre { - background-color: #ddd; - - /* Force background to be printed in Chrome */ - -webkit-print-color-adjust: exact; + direction: ltr !important; } pre > .buttons { @@ -58,22 +45,6 @@ pre, code { white-space: pre-wrap; } -svg { +.fa { display: none !important; } - -table { - color: black; - border-color: black; - background-color: unset; -} - -table thead tr { - color: black; - background-color: unset; -} - -table tbody tr { - background-color: unset; -} - diff --git a/src/theme/css/variables.css b/src/theme/css/variables.css index ea306becc..12d1db7a3 100644 --- a/src/theme/css/variables.css +++ b/src/theme/css/variables.css @@ -2,106 +2,308 @@ /* Globals */ :root { - --sidebar-width: 300px; - --page-padding: 15px; - --content-max-width: 750px; - --menu-bar-height: 50px; - --void-green: #478061; - --void-dark-green: #62b086; - --void-light: #fafafa; - --void-dark: #252525; + --sidebar-width: 300px; + --sidebar-resize-indicator-width: 8px; + --sidebar-resize-indicator-space: 2px; + --page-padding: 15px; + --content-max-width: 750px; + --menu-bar-height: 50px; + --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; + --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */ } /* Themes */ -.void-light { - --bg: #ffffff; - --fg: #333; +.ayu { + --bg: hsl(210, 25%, 8%); + --fg: #c5c5c5; - --sidebar-bg: var(--void-light); - --sidebar-fg: var(--fg); - --sidebar-active: var(--links); + --sidebar-bg: #14191f; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #5c6773; + --sidebar-active: #ffb454; + --sidebar-spacer: #2d334f; - --nav-bg: var(--void-green); - --nav-fg: var(--bg); - --nav-arrow-fg: var(--fg); - --nav-fg-hover: #000; + --scrollbar: var(--sidebar-fg); - --scrollbar: var(--sidebar-fg); + --icons: #737480; + --icons-hover: #b7b9cc; - --icons: #737480; - --icons-hover: #b7b9cc; + --links: #0096cf; - --links: var(--void-green); - --links-hover: var(--fg); + --inline-code-color: #ffb454; - --inline-code-color: #fdf6e3; - --code-border: #ccc; + --theme-popup-bg: #14191f; + --theme-popup-border: #5c6773; + --theme-hover: #191f26; - --theme-toggle-light: none; - --theme-toggle-dark: inherit; + --quote-bg: hsl(226, 15%, 17%); + --quote-border: hsl(226, 15%, 22%); - --quote-bg: #ebf4ef; - --quote-border: #d1e6da; - --quote-code-bg: var(--inline-code-color); + --warning-border: #ff8e00; - --table-border-color: var(--void-green); - --table-header-bg: var(--void-green); - --table-header-fg: #fff; - --table-alternate-bg: var(--void-light); + --table-border-color: hsl(210, 25%, 13%); + --table-header-bg: hsl(210, 25%, 28%); + --table-alternate-bg: hsl(210, 25%, 11%); - --searchbar-border-color: #aaa; - --searchbar-bg: var(--bg); - --searchbar-fg: var(--fg); - --searchbar-shadow-color: #d4c89f; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #252932; - --search-mark-bg: #e3b171; + --searchbar-border-color: #848484; + --searchbar-bg: #424242; + --searchbar-fg: #fff; + --searchbar-shadow-color: #d4c89f; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #252932; + --search-mark-bg: #e3b171; + + --color-scheme: dark; + + /* Same as `--icons` */ + --copy-button-filter: invert(45%) sepia(6%) saturate(621%) hue-rotate(198deg) brightness(99%) contrast(85%); + /* Same as `--sidebar-active` */ + --copy-button-filter-hover: invert(68%) sepia(55%) saturate(531%) hue-rotate(341deg) brightness(104%) contrast(101%); +} + +.coal { + --bg: hsl(200, 7%, 8%); + --fg: #98a3ad; + + --sidebar-bg: #292c2f; + --sidebar-fg: #a1adb8; + --sidebar-non-existant: #505254; + --sidebar-active: #3473ad; + --sidebar-spacer: #393939; + + --scrollbar: var(--sidebar-fg); + + --icons: #43484d; + --icons-hover: #b3c0cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6; + + --theme-popup-bg: #141617; + --theme-popup-border: #43484d; + --theme-hover: #1f2124; + + --quote-bg: hsl(234, 21%, 18%); + --quote-border: hsl(234, 21%, 23%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(200, 7%, 13%); + --table-header-bg: hsl(200, 7%, 28%); + --table-alternate-bg: hsl(200, 7%, 11%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #b7b7b7; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #98a3ad; + --searchresults-li-bg: #2b2b2f; + --search-mark-bg: #355c7d; + + --color-scheme: dark; + + /* Same as `--icons` */ + --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%); + /* Same as `--sidebar-active` */ + --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%); +} + +.light, html:not(.js) { + --bg: hsl(0, 0%, 100%); + --fg: hsl(0, 0%, 0%); + + --sidebar-bg: #fafafa; + --sidebar-fg: hsl(0, 0%, 0%); + --sidebar-non-existant: #aaaaaa; + --sidebar-active: #1f1fff; + --sidebar-spacer: #f4f4f4; + + --scrollbar: #8F8F8F; + + --icons: #747474; + --icons-hover: #000000; + + --links: #20609f; + + --inline-code-color: #301900; + + --theme-popup-bg: #fafafa; + --theme-popup-border: #cccccc; + --theme-hover: #e6e6e6; + + --quote-bg: hsl(197, 37%, 96%); + --quote-border: hsl(197, 37%, 91%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(0, 0%, 95%); + --table-header-bg: hsl(0, 0%, 80%); + --table-alternate-bg: hsl(0, 0%, 97%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #fafafa; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #e4f2fe; + --search-mark-bg: #a2cff5; + + --color-scheme: light; + + /* Same as `--icons` */ + --copy-button-filter: invert(45.49%); + /* Same as `--sidebar-active` */ + --copy-button-filter-hover: invert(14%) sepia(93%) saturate(4250%) hue-rotate(243deg) brightness(99%) contrast(130%); } -.void-dark { - --bg: #222; - --fg: #ccc; +.navy { + --bg: hsl(226, 23%, 11%); + --fg: #bcbdd0; + + --sidebar-bg: #282d3f; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #505274; + --sidebar-active: #2b79a2; + --sidebar-spacer: #2d334f; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #b7b9cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6; + + --theme-popup-bg: #161923; + --theme-popup-border: #737480; + --theme-hover: #282e40; + + --quote-bg: hsl(226, 15%, 17%); + --quote-border: hsl(226, 15%, 22%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(226, 23%, 16%); + --table-header-bg: hsl(226, 23%, 31%); + --table-alternate-bg: hsl(226, 23%, 14%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #aeaec6; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #5f5f71; + --searchresults-border-color: #5c5c68; + --searchresults-li-bg: #242430; + --search-mark-bg: #a2cff5; + + --color-scheme: dark; + + /* Same as `--icons` */ + --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%); + /* Same as `--sidebar-active` */ + --copy-button-filter-hover: invert(46%) sepia(20%) saturate(1537%) hue-rotate(156deg) brightness(85%) contrast(90%); +} + +.rust { + --bg: hsl(60, 9%, 87%); + --fg: #262625; + + --sidebar-bg: #3b2e2a; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #505254; + --sidebar-active: #e69f67; + --sidebar-spacer: #45373a; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #262625; + + --links: #2b79a2; + + --inline-code-color: #6e6b5e; + + --theme-popup-bg: #e1e1db; + --theme-popup-border: #b38f6b; + --theme-hover: #99908a; + + --quote-bg: hsl(60, 5%, 75%); + --quote-border: hsl(60, 5%, 70%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(60, 9%, 82%); + --table-header-bg: #b3a497; + --table-alternate-bg: hsl(60, 9%, 84%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #fafafa; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #dec2a2; + --search-mark-bg: #e69f67; + + /* Same as `--icons` */ + --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%); + /* Same as `--sidebar-active` */ + --copy-button-filter-hover: invert(77%) sepia(16%) saturate(1798%) hue-rotate(328deg) brightness(98%) contrast(83%); +} + +@media (prefers-color-scheme: dark) { + html:not(.js) { + --bg: hsl(200, 7%, 8%); + --fg: #98a3ad; + + --sidebar-bg: #292c2f; + --sidebar-fg: #a1adb8; + --sidebar-non-existant: #505254; + --sidebar-active: #3473ad; + --sidebar-spacer: #393939; + + --scrollbar: var(--sidebar-fg); - --sidebar-bg: #252525; - --sidebar-fg: var(--fg); - --sidebar-active: var(--links); + --icons: #43484d; + --icons-hover: #b3c0cc; - --nav-bg: #295340; - --nav-fg: var(--fg); - --nav-arrow-fg: var(--fg); - --nav-fg-hover: #fff; + --links: #2b79a2; - --scrollbar: var(--sidebar-fg); + --inline-code-color: #c5c8c6; - --icons: #737480; - --icons-hover: #b7b9cc; + --theme-popup-bg: #141617; + --theme-popup-border: #43484d; + --theme-hover: #1f2124; - --links: var(--void-dark-green); - --links-hover: var(--fg); + --quote-bg: hsl(234, 21%, 18%); + --quote-border: hsl(234, 21%, 23%); - --inline-code-color: #353535; - --code-border: #111; + --warning-border: #ff8e00; - --theme-toggle-light: inherit; - --theme-toggle-dark: none; + --table-border-color: hsl(200, 7%, 13%); + --table-header-bg: hsl(200, 7%, 28%); + --table-alternate-bg: hsl(200, 7%, 11%); - --quote-bg: #293d35; - --quote-border: #22362e; - --quote-code-bg: #2a2a2a; + --searchbar-border-color: #aaa; + --searchbar-bg: #b7b7b7; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #98a3ad; + --searchresults-li-bg: #2b2b2f; + --search-mark-bg: #355c7d; - --table-border-color: var(--void-green); - --table-header-bg: var(--void-green); - --table-header-fg: #fff; - --table-alternate-bg: #2c2c2c; + --color-scheme: dark; - --searchbar-border-color: #aaa; - --searchbar-bg: var(--bg); - --searchbar-fg: var(--fg); - --searchbar-shadow-color: #d4c89f; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #252932; - --search-mark-bg: #e3b171; + /* Same as `--icons` */ + --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%); + /* Same as `--sidebar-active` */ + --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%); + } } diff --git a/src/theme/index.hbs b/src/theme/index.hbs index 6090ed837..7775f262d 100644 --- a/src/theme/index.hbs +++ b/src/theme/index.hbs @@ -1,253 +1,325 @@ - - - - - {{ title }} - {{#if is_print }} - - {{/if}} - {{#if base_url}} - - {{/if}} - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
- - - - - -
- - - {{#if search_enabled}} - - {{/if}} - - - - -
- {{{ content }}} -
- - - - -
-
- - {{#if livereload}} - - - {{/if}} - - {{#if search_js}} - - - - {{/if}} - - - {{#if is_print}} - - {{/if}} - + + + + + {{ title }} + {{#if is_print }} + + {{/if}} + {{#if base_url}} + + {{/if}} + + + + {{> head}} + + + + + + {{#if favicon_svg}} + + {{/if}} + {{#if favicon_png}} + + {{/if}} + + + + {{#if print_enable}} + + {{/if}} + + + + {{#if copy_fonts}} + + {{/if}} + + + + + + + + {{#each additional_css}} + + {{/each}} + + {{#if mathjax_support}} + + + {{/if}} + + + + + + + +
+ + + + + + + + + + + + + +
+ +
+ {{> header}} + + + + {{#if search_enabled}} + + {{/if}} + + + + +
+
+ {{{ content }}} +
+ + +
+
+ + + +
+ + {{#if live_reload_endpoint}} + + + {{/if}} + + {{#if google_analytics}} + + + {{/if}} + + {{#if playground_line_numbers}} + + {{/if}} + + {{#if playground_copyable}} + + {{/if}} + + {{#if playground_js}} + + + + + + {{/if}} + + {{#if search_js}} + + + + {{/if}} + + + + + + + {{#each additional_js}} + + {{/each}} + + {{#if is_print}} + {{#if mathjax_support}} + + {{else}} + + {{/if}} + {{/if}} + +
+ From 2431bf047d992785b286b72653a520d813309123 Mon Sep 17 00:00:00 2001 From: meator Date: Sun, 4 May 2025 10:07:56 +0200 Subject: [PATCH 2/3] Reapply void-docs theme changes The contents of this commit should closely follow the patch linked in the "Void's changes to mdBook's default theme" section of https://github.com/void-linux/void-docs/issues/840 Some things had to be adapted to the newer v0.4.43 base. Some changes include: - The warning and kbd elements were left intact in general.css - -webkit-print-color-adjust was set in the pre element to match void-docs' old theme even though the new theme's code element no longer includes it in print.css - Default code fonts were left as-is (these weren't present here in the void-docs original theme) in variables.css - Warning border was left as-is (this element wasn't present in older versions of mdBook) in variables.css - copy-button-filter variables were left as-is in variables.css - variables.css no doesn't include special prefers-color-scheme: dark noscript logic (void-docs original theme didn't have it) --- src/theme/book.js | 582 +----------------------------------- src/theme/css/chrome.css | 11 +- src/theme/css/general.css | 395 +++++++++++++++--------- src/theme/css/print.css | 26 +- src/theme/css/variables.css | 308 ++++--------------- src/theme/index.hbs | 312 ++++++++----------- 6 files changed, 480 insertions(+), 1154 deletions(-) diff --git a/src/theme/book.js b/src/theme/book.js index 178f1e902..5d311a34c 100644 --- a/src/theme/book.js +++ b/src/theme/book.js @@ -3,443 +3,17 @@ // Fix back button cache problem window.onunload = function () { }; -// Global variable, shared between modules -function playground_text(playground, hidden = true) { - let code_block = playground.querySelector("code"); - - if (window.ace && code_block.classList.contains("editable")) { - let editor = window.ace.edit(code_block); - return editor.getValue(); - } else if (hidden) { - return code_block.textContent; - } else { - return code_block.innerText; - } -} - -(function codeSnippets() { - function fetch_with_timeout(url, options, timeout = 6000) { - return Promise.race([ - fetch(url, options), - new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)) - ]); - } - - var playgrounds = Array.from(document.querySelectorAll(".playground")); - if (playgrounds.length > 0) { - fetch_with_timeout("https://play.rust-lang.org/meta/crates", { - headers: { - 'Content-Type': "application/json", - }, - method: 'POST', - mode: 'cors', - }) - .then(response => response.json()) - .then(response => { - // get list of crates available in the rust playground - let playground_crates = response.crates.map(item => item["id"]); - playgrounds.forEach(block => handle_crate_list_update(block, playground_crates)); - }); - } - - function handle_crate_list_update(playground_block, playground_crates) { - // update the play buttons after receiving the response - update_play_button(playground_block, playground_crates); - - // and install on change listener to dynamically update ACE editors - if (window.ace) { - let code_block = playground_block.querySelector("code"); - if (code_block.classList.contains("editable")) { - let editor = window.ace.edit(code_block); - editor.addEventListener("change", function (e) { - update_play_button(playground_block, playground_crates); - }); - // add Ctrl-Enter command to execute rust code - editor.commands.addCommand({ - name: "run", - bindKey: { - win: "Ctrl-Enter", - mac: "Ctrl-Enter" - }, - exec: _editor => run_rust_code(playground_block) - }); - } - } - } - - // updates the visibility of play button based on `no_run` class and - // used crates vs ones available on https://play.rust-lang.org - function update_play_button(pre_block, playground_crates) { - var play_button = pre_block.querySelector(".play-button"); - - // skip if code is `no_run` - if (pre_block.querySelector('code').classList.contains("no_run")) { - play_button.classList.add("hidden"); - return; - } - - // get list of `extern crate`'s from snippet - var txt = playground_text(pre_block); - var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; - var snippet_crates = []; - var item; - while (item = re.exec(txt)) { - snippet_crates.push(item[1]); - } - - // check if all used crates are available on play.rust-lang.org - var all_available = snippet_crates.every(function (elem) { - return playground_crates.indexOf(elem) > -1; - }); - - if (all_available) { - play_button.classList.remove("hidden"); +(function theme() { + var html = document.querySelector("html"); + var themeToggleButton = document.getElementById("theme-toggle"); + + themeToggleButton.addEventListener('click', function sidebarToggle() { + if (html.classList.contains("void-light")) { + html.classList.replace("void-light", "void-dark"); + localStorage.setItem('mdbook-theme', "void-dark"); } else { - play_button.classList.add("hidden"); - } - } - - function run_rust_code(code_block) { - var result_block = code_block.querySelector(".result"); - if (!result_block) { - result_block = document.createElement('code'); - result_block.className = 'result hljs language-bash'; - - code_block.append(result_block); - } - - let text = playground_text(code_block); - let classes = code_block.querySelector('code').classList; - let edition = "2015"; - if(classes.contains("edition2018")) { - edition = "2018"; - } else if(classes.contains("edition2021")) { - edition = "2021"; - } - var params = { - version: "stable", - optimize: "0", - code: text, - edition: edition - }; - - if (text.indexOf("#![feature") !== -1) { - params.version = "nightly"; - } - - result_block.innerText = "Running..."; - - fetch_with_timeout("https://play.rust-lang.org/evaluate.json", { - headers: { - 'Content-Type': "application/json", - }, - method: 'POST', - mode: 'cors', - body: JSON.stringify(params) - }) - .then(response => response.json()) - .then(response => { - if (response.result.trim() === '') { - result_block.innerText = "No output"; - result_block.classList.add("result-no-output"); - } else { - result_block.innerText = response.result; - result_block.classList.remove("result-no-output"); - } - }) - .catch(error => result_block.innerText = "Playground Communication: " + error.message); - } - - // Syntax highlighting Configuration - hljs.configure({ - tabReplace: ' ', // 4 spaces - languages: [], // Languages used for auto-detection - }); - - let code_nodes = Array - .from(document.querySelectorAll('code')) - // Don't highlight `inline code` blocks in headers. - .filter(function (node) {return !node.parentElement.classList.contains("header"); }); - - if (window.ace) { - // language-rust class needs to be removed for editable - // blocks or highlightjs will capture events - code_nodes - .filter(function (node) {return node.classList.contains("editable"); }) - .forEach(function (block) { block.classList.remove('language-rust'); }); - - code_nodes - .filter(function (node) {return !node.classList.contains("editable"); }) - .forEach(function (block) { hljs.highlightBlock(block); }); - } else { - code_nodes.forEach(function (block) { hljs.highlightBlock(block); }); - } - - // Adding the hljs class gives code blocks the color css - // even if highlighting doesn't apply - code_nodes.forEach(function (block) { block.classList.add('hljs'); }); - - Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) { - - var lines = Array.from(block.querySelectorAll('.boring')); - // If no lines were hidden, return - if (!lines.length) { return; } - block.classList.add("hide-boring"); - - var buttons = document.createElement('div'); - buttons.className = 'buttons'; - buttons.innerHTML = ""; - - // add expand button - var pre_block = block.parentNode; - pre_block.insertBefore(buttons, pre_block.firstChild); - - pre_block.querySelector('.buttons').addEventListener('click', function (e) { - if (e.target.classList.contains('fa-eye')) { - e.target.classList.remove('fa-eye'); - e.target.classList.add('fa-eye-slash'); - e.target.title = 'Hide lines'; - e.target.setAttribute('aria-label', e.target.title); - - block.classList.remove('hide-boring'); - } else if (e.target.classList.contains('fa-eye-slash')) { - e.target.classList.remove('fa-eye-slash'); - e.target.classList.add('fa-eye'); - e.target.title = 'Show hidden lines'; - e.target.setAttribute('aria-label', e.target.title); - - block.classList.add('hide-boring'); - } - }); - }); - - if (window.playground_copyable) { - Array.from(document.querySelectorAll('pre code')).forEach(function (block) { - var pre_block = block.parentNode; - if (!pre_block.classList.contains('playground')) { - var buttons = pre_block.querySelector(".buttons"); - if (!buttons) { - buttons = document.createElement('div'); - buttons.className = 'buttons'; - pre_block.insertBefore(buttons, pre_block.firstChild); - } - - var clipButton = document.createElement('button'); - clipButton.className = 'clip-button'; - clipButton.title = 'Copy to clipboard'; - clipButton.setAttribute('aria-label', clipButton.title); - clipButton.innerHTML = ''; - - buttons.insertBefore(clipButton, buttons.firstChild); - } - }); - } - - // Process playground code blocks - Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) { - // Add play button - var buttons = pre_block.querySelector(".buttons"); - if (!buttons) { - buttons = document.createElement('div'); - buttons.className = 'buttons'; - pre_block.insertBefore(buttons, pre_block.firstChild); - } - - var runCodeButton = document.createElement('button'); - runCodeButton.className = 'fa fa-play play-button'; - runCodeButton.hidden = true; - runCodeButton.title = 'Run this code'; - runCodeButton.setAttribute('aria-label', runCodeButton.title); - - buttons.insertBefore(runCodeButton, buttons.firstChild); - runCodeButton.addEventListener('click', function (e) { - run_rust_code(pre_block); - }); - - if (window.playground_copyable) { - var copyCodeClipboardButton = document.createElement('button'); - copyCodeClipboardButton.className = 'clip-button'; - copyCodeClipboardButton.innerHTML = ''; - copyCodeClipboardButton.title = 'Copy to clipboard'; - copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title); - - buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild); - } - - let code_block = pre_block.querySelector("code"); - if (window.ace && code_block.classList.contains("editable")) { - var undoChangesButton = document.createElement('button'); - undoChangesButton.className = 'fa fa-history reset-button'; - undoChangesButton.title = 'Undo changes'; - undoChangesButton.setAttribute('aria-label', undoChangesButton.title); - - buttons.insertBefore(undoChangesButton, buttons.firstChild); - - undoChangesButton.addEventListener('click', function () { - let editor = window.ace.edit(code_block); - editor.setValue(editor.originalCode); - editor.clearSelection(); - }); - } - }); -})(); - -(function themes() { - var html = document.querySelector('html'); - var themeToggleButton = document.getElementById('theme-toggle'); - var themePopup = document.getElementById('theme-list'); - var themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); - var themeIds = []; - themePopup.querySelectorAll('button.theme').forEach(function (el) { - themeIds.push(el.id); - }); - var stylesheets = { - ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"), - tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"), - highlight: document.querySelector("[href$='highlight.css']"), - }; - - function showThemes() { - themePopup.style.display = 'block'; - themeToggleButton.setAttribute('aria-expanded', true); - themePopup.querySelector("button#" + get_theme()).focus(); - } - - function updateThemeSelected() { - themePopup.querySelectorAll('.theme-selected').forEach(function (el) { - el.classList.remove('theme-selected'); - }); - themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected'); - } - - function hideThemes() { - themePopup.style.display = 'none'; - themeToggleButton.setAttribute('aria-expanded', false); - themeToggleButton.focus(); - } - - function get_theme() { - var theme; - try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { } - if (theme === null || theme === undefined || !themeIds.includes(theme)) { - return default_theme; - } else { - return theme; - } - } - - function set_theme(theme, store = true) { - let ace_theme; - - if (theme == 'coal' || theme == 'navy') { - stylesheets.ayuHighlight.disabled = true; - stylesheets.tomorrowNight.disabled = false; - stylesheets.highlight.disabled = true; - - ace_theme = "ace/theme/tomorrow_night"; - } else if (theme == 'ayu') { - stylesheets.ayuHighlight.disabled = false; - stylesheets.tomorrowNight.disabled = true; - stylesheets.highlight.disabled = true; - ace_theme = "ace/theme/tomorrow_night"; - } else { - stylesheets.ayuHighlight.disabled = true; - stylesheets.tomorrowNight.disabled = true; - stylesheets.highlight.disabled = false; - ace_theme = "ace/theme/dawn"; - } - - setTimeout(function () { - themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor; - }, 1); - - if (window.ace && window.editors) { - window.editors.forEach(function (editor) { - editor.setTheme(ace_theme); - }); - } - - var previousTheme = get_theme(); - - if (store) { - try { localStorage.setItem('mdbook-theme', theme); } catch (e) { } - } - - html.classList.remove(previousTheme); - html.classList.add(theme); - updateThemeSelected(); - } - - // Set theme - var theme = get_theme(); - - set_theme(theme, false); - - themeToggleButton.addEventListener('click', function () { - if (themePopup.style.display === 'block') { - hideThemes(); - } else { - showThemes(); - } - }); - - themePopup.addEventListener('click', function (e) { - var theme; - if (e.target.className === "theme") { - theme = e.target.id; - } else if (e.target.parentElement.className === "theme") { - theme = e.target.parentElement.id; - } else { - return; - } - set_theme(theme); - }); - - themePopup.addEventListener('focusout', function(e) { - // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below) - if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) { - hideThemes(); - } - }); - - // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628 - document.addEventListener('click', function(e) { - if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) { - hideThemes(); - } - }); - - document.addEventListener('keydown', function (e) { - if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } - if (!themePopup.contains(e.target)) { return; } - - switch (e.key) { - case 'Escape': - e.preventDefault(); - hideThemes(); - break; - case 'ArrowUp': - e.preventDefault(); - var li = document.activeElement.parentElement; - if (li && li.previousElementSibling) { - li.previousElementSibling.querySelector('button').focus(); - } - break; - case 'ArrowDown': - e.preventDefault(); - var li = document.activeElement.parentElement; - if (li && li.nextElementSibling) { - li.nextElementSibling.querySelector('button').focus(); - } - break; - case 'Home': - e.preventDefault(); - themePopup.querySelector('li:first-child button').focus(); - break; - case 'End': - e.preventDefault(); - themePopup.querySelector('li:last-child button').focus(); - break; + html.classList.replace("void-dark", "void-light"); + localStorage.setItem('mdbook-theme', "void-light"); } }); })(); @@ -449,7 +23,6 @@ function playground_text(playground, hidden = true) { var sidebar = document.getElementById("sidebar"); var sidebarLinks = document.querySelectorAll('#sidebar a'); var sidebarToggleButton = document.getElementById("sidebar-toggle"); - var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); var firstContact = null; function showSidebar() { @@ -477,11 +50,6 @@ function playground_text(playground, hidden = true) { // Toggle sidebar sidebarToggleButton.addEventListener('click', function sidebarToggle() { if (body.classList.contains("sidebar-hidden")) { - var current_width = parseInt( - document.documentElement.style.getPropertyValue('--sidebar-width'), 10); - if (current_width < 150) { - document.documentElement.style.setProperty('--sidebar-width', '150px'); - } showSidebar(); } else if (body.classList.contains("sidebar-visible")) { hideSidebar(); @@ -494,32 +62,6 @@ function playground_text(playground, hidden = true) { } }); - sidebarResizeHandle.addEventListener('mousedown', initResize, false); - - function initResize(e) { - window.addEventListener('mousemove', resize, false); - window.addEventListener('mouseup', stopResize, false); - body.classList.add('sidebar-resizing'); - } - function resize(e) { - var pos = (e.clientX - sidebar.offsetLeft); - if (pos < 20) { - hideSidebar(); - } else { - if (body.classList.contains("sidebar-hidden")) { - showSidebar(); - } - pos = Math.min(pos, window.innerWidth - 100); - document.documentElement.style.setProperty('--sidebar-width', pos + 'px'); - } - } - //on mouseup remove windows functions mousemove & mouseup - function stopResize(e) { - body.classList.remove('sidebar-resizing'); - window.removeEventListener('mousemove', resize, false); - window.removeEventListener('mouseup', stopResize, false); - } - document.addEventListener('touchstart', function (e) { firstContact = { x: e.touches[0].clientX, @@ -584,107 +126,3 @@ function playground_text(playground, hidden = true) { } }); })(); - -(function clipboard() { - var clipButtons = document.querySelectorAll('.clip-button'); - - function hideTooltip(elem) { - elem.firstChild.innerText = ""; - elem.className = 'clip-button'; - } - - function showTooltip(elem, msg) { - elem.firstChild.innerText = msg; - elem.className = 'clip-button tooltipped'; - } - - var clipboardSnippets = new ClipboardJS('.clip-button', { - text: function (trigger) { - hideTooltip(trigger); - let playground = trigger.closest("pre"); - return playground_text(playground, false); - } - }); - - Array.from(clipButtons).forEach(function (clipButton) { - clipButton.addEventListener('mouseout', function (e) { - hideTooltip(e.currentTarget); - }); - }); - - clipboardSnippets.on('success', function (e) { - e.clearSelection(); - showTooltip(e.trigger, "Copied!"); - }); - - clipboardSnippets.on('error', function (e) { - showTooltip(e.trigger, "Clipboard error!"); - }); -})(); - -(function scrollToTop () { - var menuTitle = document.querySelector('.menu-title'); - - menuTitle.addEventListener('click', function () { - document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' }); - }); -})(); - -(function controllMenu() { - var menu = document.getElementById('menu-bar'); - - (function controllPosition() { - var scrollTop = document.scrollingElement.scrollTop; - var prevScrollTop = scrollTop; - var minMenuY = -menu.clientHeight - 50; - // When the script loads, the page can be at any scroll (e.g. if you reforesh it). - menu.style.top = scrollTop + 'px'; - // Same as parseInt(menu.style.top.slice(0, -2), but faster - var topCache = menu.style.top.slice(0, -2); - menu.classList.remove('sticky'); - var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster - document.addEventListener('scroll', function () { - scrollTop = Math.max(document.scrollingElement.scrollTop, 0); - // `null` means that it doesn't need to be updated - var nextSticky = null; - var nextTop = null; - var scrollDown = scrollTop > prevScrollTop; - var menuPosAbsoluteY = topCache - scrollTop; - if (scrollDown) { - nextSticky = false; - if (menuPosAbsoluteY > 0) { - nextTop = prevScrollTop; - } - } else { - if (menuPosAbsoluteY > 0) { - nextSticky = true; - } else if (menuPosAbsoluteY < minMenuY) { - nextTop = prevScrollTop + minMenuY; - } - } - if (nextSticky === true && stickyCache === false) { - menu.classList.add('sticky'); - stickyCache = true; - } else if (nextSticky === false && stickyCache === true) { - menu.classList.remove('sticky'); - stickyCache = false; - } - if (nextTop !== null) { - menu.style.top = nextTop + 'px'; - topCache = nextTop; - } - prevScrollTop = scrollTop; - }, { passive: true }); - })(); - (function controllBorder() { - function updateBorder() { - if (menu.offsetTop === 0) { - menu.classList.remove('bordered'); - } else { - menu.classList.add('bordered'); - } - } - updateBorder(); - document.addEventListener('scroll', updateBorder, { passive: true }); - })(); -})(); diff --git a/src/theme/css/chrome.css b/src/theme/css/chrome.css index 4cd73086d..f1cdc2c8d 100644 --- a/src/theme/css/chrome.css +++ b/src/theme/css/chrome.css @@ -153,8 +153,7 @@ html:not(.js) .left-buttons button { .nav-chapters:hover { text-decoration: none; - background-color: var(--theme-hover); - transition: background-color 0.15s, color 0.15s; + transition: color 0.15s, color 0.15s; } .nav-wrapper { @@ -294,10 +293,6 @@ pre > .buttons button.clip-button:hover::before { display: none; } } -pre > code { - display: block; - padding: 1rem; -} /* FIXME: ACE editors overlap their buttons because ACE does absolute positioning within the code block which breaks padding. The only solution I @@ -449,7 +444,7 @@ html:not(.sidebar-resizing) .sidebar { .sidebar code { line-height: 2em; } -.sidebar .sidebar-scrollbox { +/*.sidebar .sidebar-scrollbox { overflow-y: auto; position: absolute; top: 0; @@ -457,7 +452,7 @@ html:not(.sidebar-resizing) .sidebar { left: 0; right: 0; padding: 10px 10px; -} +}*/ .sidebar .sidebar-resize-handle { position: absolute; cursor: col-resize; diff --git a/src/theme/css/general.css b/src/theme/css/general.css index 0862b5167..50e71dde0 100644 --- a/src/theme/css/general.css +++ b/src/theme/css/general.css @@ -2,28 +2,44 @@ :root { /* Browser default font-size is 16px, this way 1 rem = 10px */ - font-size: 62.5%; color-scheme: var(--color-scheme); } -html { - font-family: "Open Sans", sans-serif; +body { + font-family: 'Ubuntu', sans-serif; + font-size: 1rem; + line-height: 1.5; color: var(--fg); + margin: 0; background-color: var(--bg); - text-size-adjust: none; - -webkit-text-size-adjust: none; } - -body { - margin: 0; - font-size: 1.6rem; - overflow-x: hidden; +h1, h2, h3, h4, h5, h6 { color: var(--fg); } +a, a:visited { + color: var(--links); + text-decoration: none; +} +a:hover, a:visited:hover { + color: var(--links-hover); + text-decoration: underline; } code { - font-family: var(--mono-font) !important; - font-size: var(--code-font-size); - direction: ltr !important; + background: var(--inline-code-color); + padding: 2px 4px; + border-radius: 4px; + white-space: pre-wrap; + overflow-wrap: break-word; +} +pre code { + padding: 0; + border-radius: 0; +} +pre { + padding: .5em; + margin: 1em 0; + background: var(--inline-code-color); + border: 1px solid var(--code-border); + border-radius: 4px; } /* make long words/inline code not x overflow */ @@ -36,122 +52,138 @@ main { overflow-x: auto; } -/* Don't change font size in headers. */ -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - font-size: unset; -} - -.left { float: left; } -.right { float: right; } -.boring { opacity: 0.6; } -.hide-boring .boring { display: none; } -.hidden { display: none !important; } - -h2, h3 { margin-block-start: 2.5em; } -h4, h5 { margin-block-start: 2em; } - -.header + .header h3, -.header + .header h4, -.header + .header h5 { - margin-block-start: 1em; -} - -h1:target::before, -h2:target::before, -h3:target::before, -h4:target::before, -h5:target::before, -h6:target::before { - display: inline-block; - content: "»"; - margin-inline-start: -30px; - width: 30px; -} - -/* This is broken on Safari as of version 14, but is fixed - in Safari Technology Preview 117 which I think will be Safari 14.2. - https://bugs.webkit.org/show_bug.cgi?id=218076 -*/ -:target { - /* Safari does not support logical properties */ - scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); +blockquote { + margin: 20px 0; + padding: 0 20px; + padding-left: 1em; + background: var(--quote-bg); + border: 1px solid var(--quote-border); + border-left: none; + border-right: none; } -.page { - outline: 0; - padding: 0 var(--page-padding); - margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ -} -.page-wrapper { - box-sizing: border-box; - background-color: var(--bg); -} -.no-js .page-wrapper, -.js:not(.sidebar-resizing) .page-wrapper { - transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ -} -[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper { - transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */ +blockquote code { + background: var(--quote-code-bg); } -.content { - overflow-y: auto; - padding: 0 5px 50px 5px; -} -.content main { - margin-inline-start: auto; - margin-inline-end: auto; - max-width: var(--content-max-width); -} -.content p { line-height: 1.45em; } -.content ol { line-height: 1.45em; } -.content ul { line-height: 1.45em; } -.content a { text-decoration: none; } -.content a:hover { text-decoration: underline; } -.content img, .content video { max-width: 100%; } -.content .header:link, -.content .header:visited { - color: var(--fg); -} -.content .header:link, -.content .header:visited:hover { - text-decoration: none; +li.js-unavailable { + background-color: #f6cf68; + border-radius: 10px; + margin-left: 1em; + padding-left: 1em; + padding-right: 1em; } table { - margin: 0 auto; border-collapse: collapse; + display: block; + overflow-y: auto; + border: 1px var(--table-border-color) solid; } table td { padding: 3px 20px; - border: 1px var(--table-border-color) solid; } table thead { background: var(--table-header-bg); + color: var(--table-header-fg); } table thead td { font-weight: 700; +} +table tbody tr:nth-child(2n) { + /* Alternate background colors for rows */ + background: var(--table-alternate-bg); +} + +svg { + position: relative; + top: .125em; + width: 1em; + height: auto; +} + +.hidden { + display: none; +} + +.icon-button { border: none; + background: none; + cursor: pointer; + padding: 1em; } -table thead th { - padding: 3px 20px; + +/* void navigation */ + +#void-nav { + width: 100%; + min-height: 50px; + background: var(--nav-bg); + font-size: 14px; + + display: flex; + flex-direction: row; + flex-wrap: wrap; +} +#void-nav a, +#void-nav button, +#void-nav label { + fill: var(--nav-fg); + height: 50px; + min-height: 100%; + display: block; + line-height: 50px; + padding: 0 15px; + font-size: 1.2em; +} +#void-nav ul { + list-style: none; + margin: 0; + padding: 0; +} + +#void-nav ul#nav-right { + margin-left: auto; +} + +#void-nav ul li { + display: inline-block; } -table thead tr { - border: 1px var(--table-header-bg) solid; +#void-nav ul li a { + color: var(--nav-fg); + display: block; + padding: 0 15px; + line-height: 50px; + font-size: 1.2em; + text-decoration: none +} +#void-nav ul li a:hover, +#void-nav ul li a:focus, +#void-nav button:hover, +#void-nav button:focus, +#void-nav label:hover, +#void-nav label:focus { + background: #000; } -/* Alternate background colors for rows */ -table tbody tr:nth-child(2n) { - background: var(--table-alternate-bg); + +#skip-to-content { + position: absolute; + left: -999px; + top: -999px; } +#skip-to-content:active, +#skip-to-content:focus { + position: relative; + left: 0; + top: 0; +} -blockquote { - margin: 20px 0; - padding: 0 20px; - color: var(--fg); - background-color: var(--quote-bg); - border-block-start: .1em solid var(--quote-border); - border-block-end: .1em solid var(--quote-border); +#icon-theme-light { + display: var(--theme-toggle-light); +} +#icon-theme-dark { + display: var(--theme-toggle-dark); } .warning { @@ -200,43 +232,136 @@ sup { line-height: 0; } -:not(.footnote-definition) + .footnote-definition, -.footnote-definition + :not(.footnote-definition) { - margin-block-start: 2em; +/* search */ + +#searchbar { + width: 100%; + padding: 10px 16px; + margin: 5px 0; + border-radius: 3px; + border: 1px solid var(--searchbar-border-color); +} +#searchresults-header { + font-weight: bold; + font-size: 1em; + padding: 18px 0 0 5px; +} +ul#searchresults { + list-style: none; + padding-left: 20px; +} +ul#searchresults li { + margin: 10px 0px; + padding: 2px; + border-radius: 2px; +} +ul#searchresults span.teaser { + display: block; + clear: both; + margin: 5px 0 0 20px; + font-size: 0.8em; } -.footnote-definition { - font-size: 0.9em; - margin: 0.5em 0; + +/* chapter navigation */ + +#nav-wide-wrapper { + max-width: 800px; + margin: 0 auto; + margin-top: 50px; } -.footnote-definition p { - display: inline; +.previous { + float: left; } - -.tooltiptext { - position: absolute; - visibility: hidden; - color: #fff; - background-color: #333; - transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */ - left: -8px; /* Half of the width of the icon */ - top: -35px; - font-size: 0.8em; +.next { + float: right; + right: 15px; +} +.nav-chapters { + fill: var(--nav-arrow-fg); text-align: center; - border-radius: 6px; - padding: 5px 8px; - margin: 5px; - z-index: 1000; + text-decoration: none; + display: block; + max-width: 150px; + min-width: 90px; } -.tooltipped .tooltiptext { - visibility: visible; +.nav-chapters:hover { + text-decoration: none; + fill: var(--nav-fg-hover); } -.chapter li.part-title { - color: var(--sidebar-fg); - margin: 5px 0px; - font-weight: bold; +.nav-chapters svg { + margin: 0 auto; + width: 1.5em; +} +.mobile-nav-chapters { + fill: var(--nav-arrow-fg); +} +.mobile-nav-chapters:hover { + fill: var(--nav-fg-hover); +} + +/* layout */ + +body { + box-sizing: border-box; +} +#content { + display: flex; + flex-direction: row; + width: 100%; +} +#page-wrapper { + --content-padding: 10px; + padding: 0 var(--content-padding); + width: calc(100% - var(--content-padding) * 2); +} +#search-wrapper, +#page-wrapper main { + width: 100%; + max-width: 800px; + margin: 0 auto; +} +#sidebar { + max-width: 300px; + flex-shrink: 0; } -.result-no-output { - font-style: italic; +/* 300px + 800px + 2*90px + 15px */ +@media only screen and (min-width: 1295px) { + .sidebar-visible #nav-wide-wrapper { + max-width: none; + margin: 0; + } + .sidebar-visible .nav-chapters { + background: none; + position: fixed; + top: 50px; + bottom: 0; + margin: 0; + justify-content: center; + align-content: center; + display: flex; + flex-direction: column; + } +} +/* 800px + 2*90px + 15px */ +@media only screen and (min-width: 995px) { + .sidebar-hidden #nav-wide-wrapper { + max-width: none; + margin: 0; + } + .sidebar-hidden .nav-chapters { + background: none; + position: fixed; + top: 50px; + bottom: 0; + margin: 0; + justify-content: center; + align-content: center; + display: flex; + flex-direction: column; + } + table { + display: table; + } } diff --git a/src/theme/css/print.css b/src/theme/css/print.css index 80ec3a544..8921294f8 100644 --- a/src/theme/css/print.css +++ b/src/theme/css/print.css @@ -1,6 +1,7 @@ #sidebar, #menu-bar, +#void-nav, .nav-chapters, .mobile-nav-chapters { display: none; @@ -24,6 +25,14 @@ code { direction: ltr !important; + background-color: #ddd; +} + +pre { + background-color: #ddd; + + /* Force background to be printed in Chrome */ + -webkit-print-color-adjust: exact; } pre > .buttons { @@ -45,6 +54,21 @@ pre, code { white-space: pre-wrap; } -.fa { +svg { display: none !important; } + +table { + color: black; + border-color: black; + background-color: unset; +} + +table thead tr { + color: black; + background-color: unset; +} + +table tbody tr { + background-color: unset; +} diff --git a/src/theme/css/variables.css b/src/theme/css/variables.css index 12d1db7a3..4ce5490eb 100644 --- a/src/theme/css/variables.css +++ b/src/theme/css/variables.css @@ -10,52 +10,62 @@ --menu-bar-height: 50px; --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */ + --void-green: #478061; + --void-dark-green: #62b086; + --void-light: #fafafa; + --void-dark: #252525; } /* Themes */ -.ayu { - --bg: hsl(210, 25%, 8%); - --fg: #c5c5c5; +.void-light { + --bg: #ffffff; + --fg: #333; - --sidebar-bg: #14191f; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #5c6773; - --sidebar-active: #ffb454; - --sidebar-spacer: #2d334f; + --sidebar-bg: var(--void-light); + --sidebar-fg: var(--fg); + --sidebar-active: var(--links); + + --nav-bg: var(--void-green); + --nav-fg: var(--bg); + --nav-arrow-fg: var(--fg); + --nav-fg-hover: #000; --scrollbar: var(--sidebar-fg); --icons: #737480; --icons-hover: #b7b9cc; - --links: #0096cf; + --links: var(--void-green); + --links-hover: var(--fg) - --inline-code-color: #ffb454; + --inline-code-color: #fdf6e3; + --code-border: #ccc; - --theme-popup-bg: #14191f; - --theme-popup-border: #5c6773; - --theme-hover: #191f26; + --theme-toggle-light: none; + --theme-toggle-dark: inherit; - --quote-bg: hsl(226, 15%, 17%); - --quote-border: hsl(226, 15%, 22%); + --quote-bg: #ebf4ef; + --quote-border: #d1e6da; + --quote-code-bg: var(--inline-code-color); --warning-border: #ff8e00; - --table-border-color: hsl(210, 25%, 13%); - --table-header-bg: hsl(210, 25%, 28%); - --table-alternate-bg: hsl(210, 25%, 11%); + --table-border-color: var(--void-green); + --table-header-bg: var(--void-green); + --table-header-fg: #fff; + --table-alternate-bg: var(--void-light); - --searchbar-border-color: #848484; - --searchbar-bg: #424242; - --searchbar-fg: #fff; + --searchbar-border-color: #aaa; + --searchbar-bg: var(--bg); + --searchbar-fg: var(--fg); --searchbar-shadow-color: #d4c89f; --searchresults-header-fg: #666; --searchresults-border-color: #888; --searchresults-li-bg: #252932; --search-mark-bg: #e3b171; - --color-scheme: dark; + --color-scheme: light; /* Same as `--icons` */ --copy-button-filter: invert(45%) sepia(6%) saturate(621%) hue-rotate(198deg) brightness(99%) contrast(85%); @@ -63,247 +73,57 @@ --copy-button-filter-hover: invert(68%) sepia(55%) saturate(531%) hue-rotate(341deg) brightness(104%) contrast(101%); } -.coal { - --bg: hsl(200, 7%, 8%); - --fg: #98a3ad; - - --sidebar-bg: #292c2f; - --sidebar-fg: #a1adb8; - --sidebar-non-existant: #505254; - --sidebar-active: #3473ad; - --sidebar-spacer: #393939; - - --scrollbar: var(--sidebar-fg); - - --icons: #43484d; - --icons-hover: #b3c0cc; - - --links: #2b79a2; - - --inline-code-color: #c5c8c6; - - --theme-popup-bg: #141617; - --theme-popup-border: #43484d; - --theme-hover: #1f2124; - - --quote-bg: hsl(234, 21%, 18%); - --quote-border: hsl(234, 21%, 23%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(200, 7%, 13%); - --table-header-bg: hsl(200, 7%, 28%); - --table-alternate-bg: hsl(200, 7%, 11%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #b7b7b7; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #98a3ad; - --searchresults-li-bg: #2b2b2f; - --search-mark-bg: #355c7d; - - --color-scheme: dark; - - /* Same as `--icons` */ - --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%); -} - -.light, html:not(.js) { - --bg: hsl(0, 0%, 100%); - --fg: hsl(0, 0%, 0%); - - --sidebar-bg: #fafafa; - --sidebar-fg: hsl(0, 0%, 0%); - --sidebar-non-existant: #aaaaaa; - --sidebar-active: #1f1fff; - --sidebar-spacer: #f4f4f4; - - --scrollbar: #8F8F8F; - - --icons: #747474; - --icons-hover: #000000; - - --links: #20609f; - - --inline-code-color: #301900; - - --theme-popup-bg: #fafafa; - --theme-popup-border: #cccccc; - --theme-hover: #e6e6e6; - - --quote-bg: hsl(197, 37%, 96%); - --quote-border: hsl(197, 37%, 91%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(0, 0%, 95%); - --table-header-bg: hsl(0, 0%, 80%); - --table-alternate-bg: hsl(0, 0%, 97%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #fafafa; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #e4f2fe; - --search-mark-bg: #a2cff5; +.void-dark { + --bg: #222; + --fg: #ccc; - --color-scheme: light; - - /* Same as `--icons` */ - --copy-button-filter: invert(45.49%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(14%) sepia(93%) saturate(4250%) hue-rotate(243deg) brightness(99%) contrast(130%); -} + --sidebar-bg: #252525; + --sidebar-fg: var(--fg); + --sidebar-active: var(--links); -.navy { - --bg: hsl(226, 23%, 11%); - --fg: #bcbdd0; - - --sidebar-bg: #282d3f; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #505274; - --sidebar-active: #2b79a2; - --sidebar-spacer: #2d334f; + --nav-bg: #295340; + --nav-fg: var(--fg); + --nav-arrow-fg: var(--fg); + --nav-fg-hover: #fff; --scrollbar: var(--sidebar-fg); --icons: #737480; --icons-hover: #b7b9cc; - --links: #2b79a2; - - --inline-code-color: #c5c8c6; - - --theme-popup-bg: #161923; - --theme-popup-border: #737480; - --theme-hover: #282e40; - - --quote-bg: hsl(226, 15%, 17%); - --quote-border: hsl(226, 15%, 22%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(226, 23%, 16%); - --table-header-bg: hsl(226, 23%, 31%); - --table-alternate-bg: hsl(226, 23%, 14%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #aeaec6; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #5f5f71; - --searchresults-border-color: #5c5c68; - --searchresults-li-bg: #242430; - --search-mark-bg: #a2cff5; - - --color-scheme: dark; - - /* Same as `--icons` */ - --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(46%) sepia(20%) saturate(1537%) hue-rotate(156deg) brightness(85%) contrast(90%); -} - -.rust { - --bg: hsl(60, 9%, 87%); - --fg: #262625; - - --sidebar-bg: #3b2e2a; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #505254; - --sidebar-active: #e69f67; - --sidebar-spacer: #45373a; - - --scrollbar: var(--sidebar-fg); - - --icons: #737480; - --icons-hover: #262625; - - --links: #2b79a2; + --links: var(--void-dark-green); + --links-hover: var(--fg); - --inline-code-color: #6e6b5e; + --inline-code-color: #353535; + --code-border: #111; - --theme-popup-bg: #e1e1db; - --theme-popup-border: #b38f6b; - --theme-hover: #99908a; + --theme-toggle-light: inherit; + --theme-toggle-dark: none; - --quote-bg: hsl(60, 5%, 75%); - --quote-border: hsl(60, 5%, 70%); + --quote-bg: #293d35; + --quote-border: #22362e; + --quote-code-bg: #2a2a2a; --warning-border: #ff8e00; - --table-border-color: hsl(60, 9%, 82%); - --table-header-bg: #b3a497; - --table-alternate-bg: hsl(60, 9%, 84%); + --table-border-color: var(--void-green); + --table-header-bg: var(--void-green); + --table-header-fg: #fff; + --table-alternate-bg: #2c2c2c; --searchbar-border-color: #aaa; - --searchbar-bg: #fafafa; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; + --searchbar-bg: var(--bg); + --searchbar-fg: var(--fg); + --searchbar-shadow-color: #d4c89f; --searchresults-header-fg: #666; --searchresults-border-color: #888; - --searchresults-li-bg: #dec2a2; - --search-mark-bg: #e69f67; + --searchresults-li-bg: #252932; + --search-mark-bg: #e3b171; + + --color-scheme: dark; /* Same as `--icons` */ - --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%); + --copy-button-filter: invert(45%) sepia(6%) saturate(621%) hue-rotate(198deg) brightness(99%) contrast(85%); /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(77%) sepia(16%) saturate(1798%) hue-rotate(328deg) brightness(98%) contrast(83%); -} - -@media (prefers-color-scheme: dark) { - html:not(.js) { - --bg: hsl(200, 7%, 8%); - --fg: #98a3ad; - - --sidebar-bg: #292c2f; - --sidebar-fg: #a1adb8; - --sidebar-non-existant: #505254; - --sidebar-active: #3473ad; - --sidebar-spacer: #393939; - - --scrollbar: var(--sidebar-fg); - - --icons: #43484d; - --icons-hover: #b3c0cc; - - --links: #2b79a2; - - --inline-code-color: #c5c8c6; - - --theme-popup-bg: #141617; - --theme-popup-border: #43484d; - --theme-hover: #1f2124; - - --quote-bg: hsl(234, 21%, 18%); - --quote-border: hsl(234, 21%, 23%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(200, 7%, 13%); - --table-header-bg: hsl(200, 7%, 28%); - --table-alternate-bg: hsl(200, 7%, 11%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #b7b7b7; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #98a3ad; - --searchresults-li-bg: #2b2b2f; - --search-mark-bg: #355c7d; - - --color-scheme: dark; - - /* Same as `--icons` */ - --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%); - } + --copy-button-filter-hover: invert(68%) sepia(55%) saturate(531%) hue-rotate(341deg) brightness(104%) contrast(101%); } diff --git a/src/theme/index.hbs b/src/theme/index.hbs index 7775f262d..776b34537 100644 --- a/src/theme/index.hbs +++ b/src/theme/index.hbs @@ -12,54 +12,21 @@ {{/if}} - - {{> head}} - - {{#if favicon_svg}} - - {{/if}} - {{#if favicon_png}} - {{/if}} - {{#if print_enable}} - {{/if}} - - - - {{#if copy_fonts}} - - {{/if}} - - - - - - - - {{#each additional_css}} - - {{/each}} - - {{#if mathjax_support}} - - - {{/if}} - -
@@ -92,85 +59,93 @@ - - - - - -
- -
- {{> header}} - - From 0a4bb7a7ee452a1ddd5ddc82b479d554e00530e9 Mon Sep 17 00:00:00 2001 From: meator Date: Sun, 4 May 2025 15:02:53 +0200 Subject: [PATCH 3/3] UNFINISHED --- src/theme/book.js | 32 ++++++++++++++++++++++++++++++ src/theme/css/general.css | 5 ----- src/theme/index.hbs | 41 ++++++++++++++++++++++++--------------- 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/theme/book.js b/src/theme/book.js index 5d311a34c..f5b48662a 100644 --- a/src/theme/book.js +++ b/src/theme/book.js @@ -23,6 +23,7 @@ window.onunload = function () { }; var sidebar = document.getElementById("sidebar"); var sidebarLinks = document.querySelectorAll('#sidebar a'); var sidebarToggleButton = document.getElementById("sidebar-toggle"); + var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); var firstContact = null; function showSidebar() { @@ -50,6 +51,11 @@ window.onunload = function () { }; // Toggle sidebar sidebarToggleButton.addEventListener('click', function sidebarToggle() { if (body.classList.contains("sidebar-hidden")) { + var current_width = parseInt( + document.documentElement.style.getPropertyValue('--sidebar-width'), 10); + if (current_width < 150) { + document.documentElement.style.setProperty('--sidebar-width', '150px'); + } showSidebar(); } else if (body.classList.contains("sidebar-visible")) { hideSidebar(); @@ -62,6 +68,32 @@ window.onunload = function () { }; } }); + sidebarResizeHandle.addEventListener('mousedown', initResize, false); + + function initResize(e) { + window.addEventListener('mousemove', resize, false); + window.addEventListener('mouseup', stopResize, false); + body.classList.add('sidebar-resizing'); + } + function resize(e) { + var pos = (e.clientX - sidebar.offsetLeft); + if (pos < 20) { + hideSidebar(); + } else { + if (body.classList.contains("sidebar-hidden")) { + showSidebar(); + } + pos = Math.min(pos, window.innerWidth - 100); + document.documentElement.style.setProperty('--sidebar-width', pos + 'px'); + } + } + //on mouseup remove windows functions mousemove & mouseup + function stopResize(e) { + body.classList.remove('sidebar-resizing'); + window.removeEventListener('mousemove', resize, false); + window.removeEventListener('mouseup', stopResize, false); + } + document.addEventListener('touchstart', function (e) { firstContact = { x: e.touches[0].clientX, diff --git a/src/theme/css/general.css b/src/theme/css/general.css index 50e71dde0..737796d01 100644 --- a/src/theme/css/general.css +++ b/src/theme/css/general.css @@ -264,11 +264,6 @@ ul#searchresults span.teaser { /* chapter navigation */ -#nav-wide-wrapper { - max-width: 800px; - margin: 0 auto; - margin-top: 50px; -} .previous { float: left; } diff --git a/src/theme/index.hbs b/src/theme/index.hbs index 776b34537..2c146da23 100644 --- a/src/theme/index.hbs +++ b/src/theme/index.hbs @@ -27,6 +27,8 @@ var path_to_root = "{{ path_to_root }}"; var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}"; + +
@@ -59,6 +61,29 @@ + + + + +
- - - - -
{{#if search_enabled}}