aboutsummaryrefslogtreecommitdiffhomepage
path: root/book.js
diff options
context:
space:
mode:
authorjohannst <johannst@users.noreply.github.com>2022-08-23 19:48:10 +0000
committerjohannst <johannst@users.noreply.github.com>2022-08-23 19:48:10 +0000
commit25b609d0c70d49dd62479ce03578704e62712bd8 (patch)
treef9c761f5c72ded4cf9c31bad9f15109cf810b55c /book.js
parentf647a8c45dda58078c86a96c68ae00ea1c69a222 (diff)
downloadnotes-25b609d0c70d49dd62479ce03578704e62712bd8.tar.gz
notes-25b609d0c70d49dd62479ce03578704e62712bd8.zip
deploy: 6f6fef7bb61712038220a7607447d38689ad6978
Diffstat (limited to 'book.js')
-rw-r--r--book.js216
1 files changed, 145 insertions, 71 deletions
diff --git a/book.js b/book.js
index 186f9ae..d40440c 100644
--- a/book.js
+++ b/book.js
@@ -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 });
+ })();
})();