Some updates to the help popup

This makes a few changes to the help popup:

- Move css to chrome.css, since this is a UI element.
- Move HTML code to index.hbs instead of generated in JavaScript.
  In general I prefer to keep HTML out of JavaScript when possible,
  and I didn't see a particular reason to avoid it.
- Added a click handler to dismiss the popup.
- Make sure handlers get removed when dismissed.
- Use `mdbook-` prefixes for IDs to avoid collisions with headers.
- Don't show search if it isn't enabled.
- Add the new `/` shortcut.
- Use flex layout for better positioning.
- Dim out the surrounding text using an overlay.
- Various other styling tweaks.
- Add a GUI test.
This commit is contained in:
Eric Huss 2025-05-14 18:17:16 -07:00
parent 91e94024cd
commit 33da0c26c4
6 changed files with 94 additions and 50 deletions

View file

@ -656,3 +656,46 @@ html:not(.sidebar-resizing) .sidebar {
margin-inline-start: -14px;
width: 14px;
}
/* The container for the help popup that covers the whole window. */
#mdbook-help-container {
/* Position and size for the whole window. */
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* This uses flex layout (which is set in book.js), and centers the popup
in the window.*/
display: none;
align-items: center;
justify-content: center;
z-index: 1000;
/* Dim out the book while the popup is visible. */
background: var(--overlay-bg);
}
/* The popup help box. */
#mdbook-help-popup {
box-shadow: 0 4px 24px rgba(0,0,0,0.15);
min-width: 300px;
max-width: 500px;
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
background-color: var(--bg);
color: var(--fg);
border-width: 1px;
border-color: var(--theme-popup-border);
border-style: solid;
border-radius: 8px;
padding: 10px;
}
.mdbook-help-title {
text-align: center;
/* mdbook's margin for h2 is way too large. */
margin: 10px;
}

View file

@ -277,33 +277,3 @@ sup {
.result-no-output {
font-style: italic;
}
#help-overlay {
position: fixed;
display: none;
width: 20%;
height: 60%;
top: 10%;
left: 40%;
right: 0;
bottom: 0;
background-color: rgba(225,225,225,1);
color: black;
z-index: 2;
cursor: pointer;
border-width: 3px;
border-color: black;
border-style: solid;
border-radius: 25px;
padding: 10px;
}
#help-overlay kbd {
border-width: 1px;
border-color: black;
border-style: solid;
background-color: white;
}
#help-title {
text-align: center;
}

View file

@ -64,6 +64,8 @@
--copy-button-filter-hover: invert(68%) sepia(55%) saturate(531%) hue-rotate(341deg) brightness(104%) contrast(101%);
--footnote-highlight: #2668a6;
--overlay-bg: rgba(33, 40, 48, 0.4);
}
.coal {
@ -115,6 +117,8 @@
--copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%);
--footnote-highlight: #4079ae;
--overlay-bg: rgba(33, 40, 48, 0.4);
}
.light, html:not(.js) {
@ -166,6 +170,8 @@
--copy-button-filter-hover: invert(14%) sepia(93%) saturate(4250%) hue-rotate(243deg) brightness(99%) contrast(130%);
--footnote-highlight: #7e7eff;
--overlay-bg: rgba(200, 200, 205, 0.4);
}
.navy {
@ -217,6 +223,8 @@
--copy-button-filter-hover: invert(46%) sepia(20%) saturate(1537%) hue-rotate(156deg) brightness(85%) contrast(90%);
--footnote-highlight: #4079ae;
--overlay-bg: rgba(33, 40, 48, 0.4);
}
.rust {
@ -266,6 +274,8 @@
--copy-button-filter-hover: invert(77%) sepia(16%) saturate(1798%) hue-rotate(328deg) brightness(98%) contrast(83%);
--footnote-highlight: #d3a17a;
--overlay-bg: rgba(150, 150, 150, 0.25);
}
@media (prefers-color-scheme: dark) {

View file

@ -644,30 +644,39 @@ aria-label="Show hidden lines"></button>';
}
}
function showHelp() {
document.getElementById('help-overlay').style.display = 'block';
let help = '<h2 id="help-title">Keyboard shortcuts</h2>';
help += '<p>Press <kbd>←</kbd> or <kbd>→</kbd> to navigate between chapters</p>';
help += '<p>Press <kbd>s</kbd> to search in the book</p>';
help += '<p>Press <kbd>?</kbd> to show this help</p>';
help += '<p>Press <kbd>Esc</kbd> to hide this help</p>';
const container = document.getElementById('mdbook-help-container');
const overlay = document.getElementById('mdbook-help-popup');
container.style.display = 'flex';
document.getElementById('help-overlay').innerHTML = help;
document.addEventListener('keydown', function(e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
// Clicking outside the popup will dismiss it.
const mouseHandler = event => {
if (overlay.contains(event.target)) {
return;
}
switch (e.key) {
case 'Escape':
e.preventDefault();
hideHelp();
break;
if (event.button !== 0) {
return;
}
});
event.preventDefault();
event.stopPropagation();
document.removeEventListener('mousedown', mouseHandler);
hideHelp();
};
// Pressing esc will dismiss the popup.
const escapeKeyHandler = event => {
if (event.key === 'Escape') {
event.preventDefault();
event.stopPropagation();
document.removeEventListener('keydown', escapeKeyHandler, true);
hideHelp();
}
};
document.addEventListener('keydown', escapeKeyHandler, true);
document.getElementById('mdbook-help-container')
.addEventListener('mousedown', mouseHandler);
}
function hideHelp() {
document.getElementById('help-overlay').style.display = 'none';
document.getElementById('mdbook-help-container').style.display = 'none';
}
// Usually needs the Shift key to be pressed

View file

@ -63,7 +63,19 @@
<script src="{{ resource "toc.js" }}"></script>
</head>
<body>
<div id="help-overlay"></div>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd>←</kbd> or <kbd>→</kbd> to navigate between chapters</p>
{{#if search_enabled}}
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
{{/if}}
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>

View file

@ -667,7 +667,7 @@ fn build_header_links(html: &str) -> String {
static BUILD_HEADER_LINKS: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r#"<h(\d)(?: id="([^"]+)")?(?: class="([^"]+)")?>(.*?)</h\d>"#).unwrap()
});
static IGNORE_CLASS: &[&str] = &["menu-title"];
static IGNORE_CLASS: &[&str] = &["menu-title", "mdbook-help-title"];
let mut id_counter = HashMap::new();