diff options
author | johannst <johannst@users.noreply.github.com> | 2022-08-23 19:48:10 +0000 |
---|---|---|
committer | johannst <johannst@users.noreply.github.com> | 2022-08-23 19:48:10 +0000 |
commit | 25b609d0c70d49dd62479ce03578704e62712bd8 (patch) | |
tree | f9c761f5c72ded4cf9c31bad9f15109cf810b55c /book.js | |
parent | f647a8c45dda58078c86a96c68ae00ea1c69a222 (diff) | |
download | notes-25b609d0c70d49dd62479ce03578704e62712bd8.tar.gz notes-25b609d0c70d49dd62479ce03578704e62712bd8.zip |
deploy: 6f6fef7bb61712038220a7607447d38689ad6978
Diffstat (limited to 'book.js')
-rw-r--r-- | book.js | 216 |
1 files changed, 145 insertions, 71 deletions
@@ -4,8 +4,8 @@ window.onunload = function () { }; // Global variable, shared between modules -function playpen_text(playpen) { - let code_block = playpen.querySelector("code"); +function playground_text(playground) { + let code_block = playground.querySelector("code"); if (window.ace && code_block.classList.contains("editable")) { let editor = window.ace.edit(code_block); @@ -23,8 +23,8 @@ function playpen_text(playpen) { ]); } - var playpens = Array.from(document.querySelectorAll(".playpen")); - if (playpens.length > 0) { + 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", @@ -36,21 +36,21 @@ function playpen_text(playpen) { .then(response => { // get list of crates available in the rust playground let playground_crates = response.crates.map(item => item["id"]); - playpens.forEach(block => handle_crate_list_update(block, playground_crates)); + playgrounds.forEach(block => handle_crate_list_update(block, playground_crates)); }); } - function handle_crate_list_update(playpen_block, playground_crates) { + function handle_crate_list_update(playground_block, playground_crates) { // update the play buttons after receiving the response - update_play_button(playpen_block, playground_crates); + update_play_button(playground_block, playground_crates); // and install on change listener to dynamically update ACE editors if (window.ace) { - let code_block = playpen_block.querySelector("code"); + 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(playpen_block, playground_crates); + update_play_button(playground_block, playground_crates); }); // add Ctrl-Enter command to execute rust code editor.commands.addCommand({ @@ -59,7 +59,7 @@ function playpen_text(playpen) { win: "Ctrl-Enter", mac: "Ctrl-Enter" }, - exec: _editor => run_rust_code(playpen_block) + exec: _editor => run_rust_code(playground_block) }); } } @@ -77,7 +77,7 @@ function playpen_text(playpen) { } // get list of `extern crate`'s from snippet - var txt = playpen_text(pre_block); + var txt = playground_text(pre_block); var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; var snippet_crates = []; var item; @@ -106,11 +106,14 @@ function playpen_text(playpen) { code_block.append(result_block); } - let text = playpen_text(code_block); + let text = playground_text(code_block); let classes = code_block.querySelector('code').classList; - let has_2018 = classes.contains("edition2018"); - let edition = has_2018 ? "2018" : "2015"; - + let edition = "2015"; + if(classes.contains("edition2018")) { + edition = "2018"; + } else if(classes.contains("edition2021")) { + edition = "2021"; + } var params = { version: "stable", optimize: "0", @@ -133,7 +136,15 @@ function playpen_text(playpen) { body: JSON.stringify(params) }) .then(response => response.json()) - .then(response => result_block.innerText = response.result) + .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); } @@ -143,27 +154,29 @@ function playpen_text(playpen) { 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 - Array - .from(document.querySelectorAll('code.editable')) + code_nodes + .filter(function (node) {return node.classList.contains("editable"); }) .forEach(function (block) { block.classList.remove('language-rust'); }); Array - .from(document.querySelectorAll('code:not(.editable)')) + code_nodes + .filter(function (node) {return !node.classList.contains("editable"); }) .forEach(function (block) { hljs.highlightBlock(block); }); } else { - Array - .from(document.querySelectorAll('code')) - .forEach(function (block) { hljs.highlightBlock(block); }); + code_nodes.forEach(function (block) { hljs.highlightBlock(block); }); } // Adding the hljs class gives code blocks the color css // even if highlighting doesn't apply - Array - .from(document.querySelectorAll('code')) - .forEach(function (block) { block.classList.add('hljs'); }); + code_nodes.forEach(function (block) { block.classList.add('hljs'); }); Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) { @@ -174,23 +187,23 @@ function playpen_text(playpen) { var buttons = document.createElement('div'); buttons.className = 'buttons'; - buttons.innerHTML = "<button class=\"fa fa-expand\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>"; + buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>"; // 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-expand')) { - e.target.classList.remove('fa-expand'); - e.target.classList.add('fa-compress'); + 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-compress')) { - e.target.classList.remove('fa-compress'); - e.target.classList.add('fa-expand'); + } 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); @@ -199,10 +212,10 @@ function playpen_text(playpen) { }); }); - if (window.playpen_copyable) { + if (window.playground_copyable) { Array.from(document.querySelectorAll('pre code')).forEach(function (block) { var pre_block = block.parentNode; - if (!pre_block.classList.contains('playpen')) { + if (!pre_block.classList.contains('playground')) { var buttons = pre_block.querySelector(".buttons"); if (!buttons) { buttons = document.createElement('div'); @@ -221,8 +234,8 @@ function playpen_text(playpen) { }); } - // Process playpen code blocks - Array.from(document.querySelectorAll(".playpen")).forEach(function (pre_block) { + // Process playground code blocks + Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) { // Add play button var buttons = pre_block.querySelector(".buttons"); if (!buttons) { @@ -242,7 +255,7 @@ function playpen_text(playpen) { run_rust_code(pre_block); }); - if (window.playpen_copyable) { + if (window.playground_copyable) { var copyCodeClipboardButton = document.createElement('button'); copyCodeClipboardButton.className = 'fa fa-copy clip-button'; copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>'; @@ -284,7 +297,7 @@ function playpen_text(playpen) { function showThemes() { themePopup.style.display = 'block'; themeToggleButton.setAttribute('aria-expanded', true); - themePopup.querySelector("button#" + document.body.className).focus(); + themePopup.querySelector("button#" + get_theme()).focus(); } function hideThemes() { @@ -293,6 +306,16 @@ function playpen_text(playpen) { themeToggleButton.focus(); } + function get_theme() { + var theme; + try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { } + if (theme === null || theme === undefined) { + return default_theme; + } else { + return theme; + } + } + function set_theme(theme, store = true) { let ace_theme; @@ -324,9 +347,7 @@ function playpen_text(playpen) { }); } - var previousTheme; - try { previousTheme = localStorage.getItem('mdbook-theme'); } catch (e) { } - if (previousTheme === null || previousTheme === undefined) { previousTheme = default_theme; } + var previousTheme = get_theme(); if (store) { try { localStorage.setItem('mdbook-theme', theme); } catch (e) { } @@ -337,9 +358,7 @@ function playpen_text(playpen) { } // Set theme - var theme; - try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { } - if (theme === null || theme === undefined) { theme = default_theme; } + var theme = get_theme(); set_theme(theme, false); @@ -352,7 +371,14 @@ function playpen_text(playpen) { }); themePopup.addEventListener('click', function (e) { - var theme = e.target.id || e.target.parentElement.id; + 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); }); @@ -408,7 +434,6 @@ function playpen_text(playpen) { (function sidebar() { var html = document.querySelector("html"); var sidebar = document.getElementById("sidebar"); - var sidebarScrollBox = document.getElementById("sidebar-scrollbox"); var sidebarLinks = document.querySelectorAll('#sidebar a'); var sidebarToggleButton = document.getElementById("sidebar-toggle"); var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); @@ -450,6 +475,11 @@ function playpen_text(playpen) { // Toggle sidebar sidebarToggleButton.addEventListener('click', function sidebarToggle() { if (html.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")) { hideSidebar(); @@ -470,7 +500,16 @@ function playpen_text(playpen) { html.classList.add('sidebar-resizing'); } function resize(e) { - document.documentElement.style.setProperty('--sidebar-width', (e.clientX - sidebar.offsetLeft) + 'px'); + var pos = (e.clientX - sidebar.offsetLeft); + if (pos < 20) { + hideSidebar(); + } else { + if (html.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) { @@ -505,9 +544,10 @@ function playpen_text(playpen) { }, { passive: true }); // Scroll sidebar to current active section - var activeSection = sidebar.querySelector(".active"); + var activeSection = document.getElementById("sidebar").querySelector(".active"); if (activeSection) { - sidebarScrollBox.scrollTop = activeSection.offsetTop; + // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView + activeSection.scrollIntoView({ block: 'center' }); } })(); @@ -551,8 +591,8 @@ function playpen_text(playpen) { var clipboardSnippets = new ClipboardJS('.clip-button', { text: function (trigger) { hideTooltip(trigger); - let playpen = trigger.closest("pre"); - return playpen_text(playpen); + let playground = trigger.closest("pre"); + return playground_text(playground); } }); @@ -580,26 +620,60 @@ function playpen_text(playpen) { }); })(); -(function autoHideMenu() { +(function controllMenu() { var menu = document.getElementById('menu-bar'); - var previousScrollTop = document.scrollingElement.scrollTop; - - document.addEventListener('scroll', function () { - if (menu.classList.contains('folded') && document.scrollingElement.scrollTop < previousScrollTop) { - menu.classList.remove('folded'); - } else if (!menu.classList.contains('folded') && document.scrollingElement.scrollTop > previousScrollTop) { - menu.classList.add('folded'); - } - - if (!menu.classList.contains('bordered') && document.scrollingElement.scrollTop > 0) { - menu.classList.add('bordered'); - } - - if (menu.classList.contains('bordered') && document.scrollingElement.scrollTop === 0) { - menu.classList.remove('bordered'); - } - - previousScrollTop = Math.max(document.scrollingElement.scrollTop, 0); - }, { passive: true }); + (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() { + menu.classList.remove('bordered'); + document.addEventListener('scroll', function () { + if (menu.offsetTop === 0) { + menu.classList.remove('bordered'); + } else { + menu.classList.add('bordered'); + } + }, { passive: true }); + })(); })(); |