Add shortkey settings
This commit is contained in:
parent
b5ffc734a2
commit
3f0ee6d925
|
@ -21,7 +21,7 @@ In that situation, the menu icon (three horizontal bars) at the top-left of the
|
||||||
|
|
||||||
The **arrow buttons** at the bottom of the page can be used to navigate to the previous or the next chapter.
|
The **arrow buttons** at the bottom of the page can be used to navigate to the previous or the next chapter.
|
||||||
|
|
||||||
The **left and right arrow keys** on the keyboard can be used to navigate to the previous or the next chapter.
|
Pressing <kbd>Ctrl</kbd>+<kbd>←</kbd> and <kbd>Ctrl</kbd>+<kbd>→</kbd> (<kbd>⌘</kbd>+<kbd>←</kbd> and <kbd>⌘</kbd>+<kbd>→</kbd> on Mac) on the keyboard can be used to navigate to the previous or the next chapter.
|
||||||
|
|
||||||
## Top menu bar
|
## Top menu bar
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ The icons displayed will depend on the settings of how the book was generated.
|
||||||
| Icon | Description |
|
| Icon | Description |
|
||||||
|------|-------------|
|
|------|-------------|
|
||||||
| <i class="fa fa-bars"></i> | Opens and closes the chapter listing sidebar. |
|
| <i class="fa fa-bars"></i> | Opens and closes the chapter listing sidebar. |
|
||||||
| <i class="fa fa-paint-brush"></i> | Opens a picker to choose a different color theme. |
|
| <i class="fa fa-cog"></i> | Opens a settings menu for setting a different color theme or shortcut keys. |
|
||||||
| <i class="fa fa-search"></i> | Opens a search bar for searching within the book. |
|
| <i class="fa fa-search"></i> | Opens a search bar for searching within the book. |
|
||||||
| <i class="fa fa-print"></i> | Instructs the web browser to print the entire book. |
|
| <i class="fa fa-print"></i> | Instructs the web browser to print the entire book. |
|
||||||
| <i class="fa fa-github"></i> | Opens a link to the website that hosts the source code of the book. |
|
| <i class="fa fa-github"></i> | Opens a link to the website that hosts the source code of the book. |
|
||||||
|
|
|
@ -285,9 +285,7 @@ function playground_text(playground, hidden = true) {
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function themes() {
|
(function themes() {
|
||||||
var html = document.querySelector('html');
|
var html = document.documentElement;
|
||||||
var themeToggleButton = document.getElementById('theme-toggle');
|
|
||||||
var themePopup = document.getElementById('theme-list');
|
|
||||||
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
||||||
var stylesheets = {
|
var stylesheets = {
|
||||||
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
|
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
|
||||||
|
@ -295,30 +293,11 @@ function playground_text(playground, hidden = true) {
|
||||||
highlight: document.querySelector("[href$='highlight.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() {
|
function get_theme() {
|
||||||
var theme;
|
var theme;
|
||||||
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
|
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
|
||||||
if (theme === null || theme === undefined) {
|
if (theme === null || theme === undefined) {
|
||||||
return default_theme;
|
return window.default_theme;
|
||||||
} else {
|
} else {
|
||||||
return theme;
|
return theme;
|
||||||
}
|
}
|
||||||
|
@ -363,81 +342,11 @@ function playground_text(playground, hidden = true) {
|
||||||
|
|
||||||
html.classList.remove(previousTheme);
|
html.classList.remove(previousTheme);
|
||||||
html.classList.add(theme);
|
html.classList.add(theme);
|
||||||
updateThemeSelected();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set theme
|
set_theme(get_theme(), false);
|
||||||
var theme = get_theme();
|
|
||||||
|
|
||||||
set_theme(theme, false);
|
window.set_theme = set_theme;
|
||||||
|
|
||||||
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() {
|
(function sidebar() {
|
||||||
|
@ -560,30 +469,6 @@ function playground_text(playground, hidden = true) {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(function chapterNavigation() {
|
|
||||||
document.addEventListener('keydown', function (e) {
|
|
||||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
|
||||||
if (window.search && window.search.hasFocus()) { return; }
|
|
||||||
|
|
||||||
switch (e.key) {
|
|
||||||
case 'ArrowRight':
|
|
||||||
e.preventDefault();
|
|
||||||
var nextButton = document.querySelector('.nav-chapters.next');
|
|
||||||
if (nextButton) {
|
|
||||||
window.location.href = nextButton.href;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'ArrowLeft':
|
|
||||||
e.preventDefault();
|
|
||||||
var previousButton = document.querySelector('.nav-chapters.previous');
|
|
||||||
if (previousButton) {
|
|
||||||
window.location.href = previousButton.href;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function clipboard() {
|
(function clipboard() {
|
||||||
var clipButtons = document.querySelectorAll('.clip-button');
|
var clipButtons = document.querySelectorAll('.clip-button');
|
||||||
|
|
||||||
|
@ -686,3 +571,311 @@ function playground_text(playground, hidden = true) {
|
||||||
}, { passive: true });
|
}, { passive: true });
|
||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
(function settings() {
|
||||||
|
const toggle = document.querySelector("#settings-toggle");
|
||||||
|
const menu = document.querySelector("#settings-menu");
|
||||||
|
|
||||||
|
const isMac = /^Mac/i.test(navigator.userAgentData?.platform ?? navigator.platform);
|
||||||
|
const isTouchDevice = window.matchMedia("(pointer: coarse)").matches;
|
||||||
|
|
||||||
|
const eventModifiers = Object.fromEntries(["ctrl", "alt", "shift", "meta"]
|
||||||
|
.map((k) => [k, `${k}Key`]));
|
||||||
|
|
||||||
|
const defaultComboModifier = isMac ? "Meta" : "Control";
|
||||||
|
|
||||||
|
const defaultShortkeys = [
|
||||||
|
{
|
||||||
|
id: "toc",
|
||||||
|
name: "Toggle Table of Contents",
|
||||||
|
combo: "t",
|
||||||
|
selector: "#sidebar-toggle",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "settings",
|
||||||
|
name: "Open settings",
|
||||||
|
combo: "/",
|
||||||
|
selector: "#settings-toggle",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "search",
|
||||||
|
name: "Search",
|
||||||
|
combo: "s",
|
||||||
|
selector: "#search-toggle",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "previous",
|
||||||
|
name: "Previous chapter",
|
||||||
|
combo: `${defaultComboModifier}+ArrowLeft`,
|
||||||
|
selector: ".nav-chapters.previous",
|
||||||
|
altSelectors: [".mobile-nav-chapters.previous"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "next",
|
||||||
|
name: "Next chapter",
|
||||||
|
combo: `${defaultComboModifier}+ArrowRight`,
|
||||||
|
selector: ".nav-chapters.next",
|
||||||
|
altSelectors: [".mobile-nav-chapters.next"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function getCombo(storageKey) {
|
||||||
|
const shortkey = localStorage.getItem(`mdbook-shortkeys::${storageKey}`);
|
||||||
|
return shortkey ?? defaultShortkeys.find((x) => x.id === storageKey).combo;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCombo(storageKey, combo) {
|
||||||
|
localStorage.setItem(`mdbook-shortkeys::${storageKey}`, combo);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkIsTextInputMode() {
|
||||||
|
return document.activeElement.isContentEditable ||
|
||||||
|
["INPUT", "TEXTAREA"].includes(document.activeElement.nodeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
function eventToCombo(e) {
|
||||||
|
const normalized = new Map([
|
||||||
|
[" ", "Space"],
|
||||||
|
["+", "Plus"],
|
||||||
|
["Ctrl", "Control"],
|
||||||
|
]);
|
||||||
|
|
||||||
|
const modifierKeys = Object.keys(eventModifiers)
|
||||||
|
.filter((k) => e[eventModifiers[k]])
|
||||||
|
.map((x) => x.charAt(0).toUpperCase() + x.slice(1));
|
||||||
|
|
||||||
|
if (["Control", "Alt", "Shift", "Meta"].includes(e.key)) return null;
|
||||||
|
|
||||||
|
return [...modifierKeys, e.key]
|
||||||
|
.map((x) => normalized.has(x) ? normalized.get(x) : x).join("+");
|
||||||
|
}
|
||||||
|
|
||||||
|
function eventMatchesCombo(e, combo) {
|
||||||
|
const eventCombo = eventToCombo(e);
|
||||||
|
return eventCombo && (eventCombo === combo);
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyToPretty(key) {
|
||||||
|
const fmtMap = new Map([
|
||||||
|
["ArrowRight", "→"],
|
||||||
|
["ArrowLeft", "←"],
|
||||||
|
["ArrowUp", "↑"],
|
||||||
|
["ArrowDown", "↓"],
|
||||||
|
["Plus", "+"],
|
||||||
|
["Control", isMac ? "Control" : "Ctrl"],
|
||||||
|
["Alt", isMac ? "⌥" : "Alt"],
|
||||||
|
["Meta", isMac ? "⌘" : "Meta"],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return fmtMap.has(key) ? fmtMap.get(key) : key;
|
||||||
|
}
|
||||||
|
|
||||||
|
function comboToPretty(combo) {
|
||||||
|
return combo.split("+").map(keyToPretty).join("+");
|
||||||
|
}
|
||||||
|
|
||||||
|
function comboToPrettyHtml(combo) {
|
||||||
|
const html = (text) =>
|
||||||
|
Object.assign(document.createElement("span"), { textContent: text })
|
||||||
|
.innerHTML;
|
||||||
|
|
||||||
|
return combo.split("+").map((x) => `<kbd>${html(keyToPretty(x))}</kbd>`).join(
|
||||||
|
"<span>+</span>",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderShortkeyField(shortkey) {
|
||||||
|
const div = document.createElement("div");
|
||||||
|
|
||||||
|
const combo = getCombo(shortkey.id);
|
||||||
|
const touched = combo !== shortkey.combo;
|
||||||
|
const changeLabel = `Change shortcut key for ${shortkey.name}`;
|
||||||
|
const buttonAttrs = (label) =>
|
||||||
|
`aria-label="${label}" title="${label}" aria-controls="shortkey-${shortkey.id}"`;
|
||||||
|
|
||||||
|
div.classList.add("shortkey");
|
||||||
|
div.innerHTML = `<label for="shortkey-${shortkey.id}">${shortkey.name}</label>
|
||||||
|
<div class="shortkey__control${
|
||||||
|
touched ? " shortkey__control--touched" : ""
|
||||||
|
}" data-shortkey-item="${shortkey.id}">
|
||||||
|
<span class="shortkey__input">
|
||||||
|
<input${
|
||||||
|
touched ? "" : " disabled"
|
||||||
|
} id="shortkey-${shortkey.id}" autocomplete="off" value="Control+ArrowLeft">
|
||||||
|
<span aria-hidden="true" class="shortkey__display">${
|
||||||
|
comboToPrettyHtml(combo)
|
||||||
|
}</span>
|
||||||
|
</span>
|
||||||
|
<button class="shortkey__change" type="button" ${buttonAttrs(changeLabel)}>
|
||||||
|
<i class="fa fa-pencil" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.innerHTML = `
|
||||||
|
<h2>Settings</h2>
|
||||||
|
<fieldset>
|
||||||
|
<legend>
|
||||||
|
<span>Appearance</span>
|
||||||
|
</legend>
|
||||||
|
<div>
|
||||||
|
<label for="theme">Theme</label>
|
||||||
|
<select id="theme">
|
||||||
|
${["light", "rust", "coal", "navy", "ayu"].map((theme) =>
|
||||||
|
`<option${(localStorage.getItem("mdbook-theme") ?? window.default_theme) ===
|
||||||
|
theme
|
||||||
|
? " selected"
|
||||||
|
: ""
|
||||||
|
} value="${theme}">${theme.charAt(0).toUpperCase() + theme.slice(1)}</option>`
|
||||||
|
).join("")
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
${isTouchDevice ? "" : `<fieldset id="shortkeys" class="shortkeys">
|
||||||
|
<legend>
|
||||||
|
<span>Keyboard shortcuts</span>
|
||||||
|
</legend>
|
||||||
|
${defaultShortkeys.map((x) => renderShortkeyField(x).outerHTML).join("")}
|
||||||
|
<div>
|
||||||
|
<button class="shortkeys__reset-all" type="reset">
|
||||||
|
Reset all keyboard shortcuts
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</fieldset>`}
|
||||||
|
`;
|
||||||
|
|
||||||
|
function updateButtons() {
|
||||||
|
for (const shortkey of defaultShortkeys) {
|
||||||
|
for (
|
||||||
|
const button of document.querySelectorAll(
|
||||||
|
[shortkey.selector, ...(shortkey.altSelectors ?? [])].join(", "),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const combo = getCombo(shortkey.id);
|
||||||
|
button.setAttribute("aria-keyshortcuts", combo);
|
||||||
|
button.title = button.title.replace(
|
||||||
|
/(?: \(.+\))?$/,
|
||||||
|
` (${comboToPretty(combo)})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateButtons();
|
||||||
|
|
||||||
|
function toggleSettingsPopup(open = toggle.getAttribute("aria-expanded") !== "true") {
|
||||||
|
toggle.setAttribute("aria-expanded", String(open));
|
||||||
|
menu.hidden = !open;
|
||||||
|
|
||||||
|
if (open) {
|
||||||
|
menu.querySelector("input, button, textarea, select").focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle.addEventListener("click", () => toggleSettingsPopup());
|
||||||
|
menu.addEventListener("submit", (e) => e.preventDefault());
|
||||||
|
menu.addEventListener("change", updateButtons);
|
||||||
|
|
||||||
|
menu.querySelector("#theme").addEventListener("change", (e) => {
|
||||||
|
window.set_theme(e.target.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addEventListener("keydown", (e) => {
|
||||||
|
if (!e.target.matches(".shortkey__control input")) return;
|
||||||
|
if (["Escape", "Tab", "Enter", " "].includes(e.key)) return;
|
||||||
|
|
||||||
|
const parent = e.target.closest(".shortkey__control");
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
const combo = eventToCombo(e);
|
||||||
|
|
||||||
|
if (!combo) return;
|
||||||
|
|
||||||
|
const html = comboToPrettyHtml(combo);
|
||||||
|
|
||||||
|
setCombo(parent.dataset.shortkeyItem, combo);
|
||||||
|
e.target.value = combo;
|
||||||
|
e.currentTarget.dispatchEvent(new Event("change"));
|
||||||
|
|
||||||
|
parent.querySelector(".shortkey__display").innerHTML = html;
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addEventListener("click", (e) => {
|
||||||
|
if (e.target.closest(".shortkey__control .shortkey__change")) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const input = e.target.closest(".shortkey__control").querySelector(
|
||||||
|
"input",
|
||||||
|
);
|
||||||
|
input.disabled = false;
|
||||||
|
e.target.closest(".shortkey__control").classList.add(
|
||||||
|
"shortkey__control--touched",
|
||||||
|
);
|
||||||
|
input.focus();
|
||||||
|
} else if (e.target.closest("#shortkeys .shortkeys__reset-all")) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
for (const el of e.currentTarget.querySelectorAll(".shortkey__control")) {
|
||||||
|
const shortkey = defaultShortkeys.find((x) =>
|
||||||
|
x.id === el.dataset.shortkeyItem
|
||||||
|
);
|
||||||
|
|
||||||
|
setCombo(el.dataset.shortkeyItem, shortkey.combo);
|
||||||
|
el.closest(".shortkey").replaceWith(renderShortkeyField(shortkey));
|
||||||
|
}
|
||||||
|
e.currentTarget.dispatchEvent(new Event("change"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.addEventListener("focusout", (e) => {
|
||||||
|
if (e.target.matches(".shortkey__control input")) {
|
||||||
|
e.target.closest(".shortkey").replaceWith(
|
||||||
|
renderShortkeyField(
|
||||||
|
defaultShortkeys.find((x) =>
|
||||||
|
x.id === e.target.closest(".shortkey__control").dataset.shortkeyItem
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("keydown", (e) => {
|
||||||
|
if (checkIsTextInputMode()) return;
|
||||||
|
|
||||||
|
for (const shortkey of defaultShortkeys) {
|
||||||
|
if (eventMatchesCombo(e, getCombo(shortkey.id))) {
|
||||||
|
e.preventDefault();
|
||||||
|
const button = document.querySelector(shortkey.selector);
|
||||||
|
if (button) {
|
||||||
|
button.focus();
|
||||||
|
button.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("keydown", (e) => {
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
if (e.target.closest("#settings-menu")) {
|
||||||
|
toggleSettingsPopup(false);
|
||||||
|
toggle.focus();
|
||||||
|
} else if (!checkIsTextInputMode()) {
|
||||||
|
toggleSettingsPopup(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("click", (e) => {
|
||||||
|
if (
|
||||||
|
e.isTrusted && !e.target.closest("#settings-menu") &&
|
||||||
|
!e.target.closest("#settings-toggle")
|
||||||
|
) {
|
||||||
|
toggleSettingsPopup(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
|
@ -87,6 +87,7 @@ a > .hljs {
|
||||||
}
|
}
|
||||||
.right-buttons a {
|
.right-buttons a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.left-buttons {
|
.left-buttons {
|
||||||
|
@ -139,8 +140,6 @@ a > .hljs {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
max-width: 150px;
|
max-width: 150px;
|
||||||
min-width: 90px;
|
min-width: 90px;
|
||||||
|
@ -151,6 +150,10 @@ a > .hljs {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
transition: color 0.5s, background-color 0.5s;
|
transition: color 0.5s, background-color 0.5s;
|
||||||
|
|
||||||
|
height: 10rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-chapters:hover {
|
.nav-chapters:hover {
|
||||||
|
@ -498,48 +501,127 @@ ul#searchresults span.teaser em {
|
||||||
line-height: 1.9em;
|
line-height: 1.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Theme Menu Popup */
|
/* Settings menu */
|
||||||
|
|
||||||
.theme-popup {
|
#settings-menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
inset-inline-start: 10px;
|
||||||
top: var(--menu-bar-height);
|
inset-block-start: var(--menu-bar-height);
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 0.7em;
|
font-size: 0.7em;
|
||||||
color: var(--fg);
|
color: var(--fg);
|
||||||
background: var(--theme-popup-bg);
|
background: var(--theme-popup-bg);
|
||||||
border: 1px solid var(--theme-popup-border);
|
border: 1px solid var(--theme-popup-border);
|
||||||
margin: 0;
|
width: 32rem;
|
||||||
padding: 0;
|
|
||||||
list-style: none;
|
|
||||||
display: none;
|
|
||||||
/* Don't let the children's background extend past the rounded corners. */
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
.theme-popup .default {
|
|
||||||
color: var(--icons);
|
#settings-menu * {
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.theme-popup .theme {
|
|
||||||
|
#settings-menu h2 {
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-menu fieldset {
|
||||||
|
margin: 1rem;
|
||||||
|
border: 1px solid var(--theme-popup-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-menu select {
|
||||||
|
display: block;
|
||||||
|
padding: 0.6rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 2px 20px;
|
|
||||||
line-height: 25px;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-align: left;
|
|
||||||
cursor: pointer;
|
|
||||||
color: inherit;
|
|
||||||
background: inherit;
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
}
|
||||||
.theme-popup .theme:hover {
|
|
||||||
|
#settings-menu :is(select, input) {
|
||||||
|
border: 1px solid var(--searchbar-border-color);
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: var(--searchbar-bg);
|
||||||
|
transition: box-shadow 300ms ease-in-out;
|
||||||
|
color: var(--searchbar-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortkey__control {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-menu .shortkey__input {
|
||||||
|
flex: 0 1 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-menu .shortkey__control input {
|
||||||
|
height: 3.2rem;
|
||||||
|
color: #00000001;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-menu .shortkey__control input:disabled {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-menu .shortkey__control input::selection {
|
||||||
|
color: transparent;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortkey__control.shortkey__control--touched .shortkey__change {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortkey__control .shortkey__display {
|
||||||
|
position: absolute;
|
||||||
|
inset-inline-start: 0.8rem;
|
||||||
|
inset-block-start: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortkey__control.shortkey__control--touched .shortkey__display span {
|
||||||
|
color: var(--searchbar-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortkey__control button {
|
||||||
|
height: 3rem;
|
||||||
|
color: var(--fg);
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortkey__control :is(button:hover, button i:hover) {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--links);
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu-bar .shortkey__control button i {
|
||||||
|
line-height: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-menu .shortkeys__reset-all {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.5rem 0.8rem;
|
||||||
|
font-size: 14px;
|
||||||
|
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);
|
||||||
|
margin-block-start: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings-menu .shortkeys__reset-all:hover {
|
||||||
|
color: var(--fg);
|
||||||
|
border-color: var(--icons-hover);
|
||||||
background-color: var(--theme-hover);
|
background-color: var(--theme-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-selected::before {
|
.shortkeys > * {
|
||||||
display: inline-block;
|
margin-block: 0.3rem;
|
||||||
content: "✓";
|
|
||||||
margin-left: -14px;
|
|
||||||
width: 14px;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,18 +120,12 @@
|
||||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||||
<i class="fa fa-bars"></i>
|
<i class="fa fa-bars"></i>
|
||||||
</button>
|
</button>
|
||||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
<button id="settings-toggle" class="icon-button" type="button" title="Settings" aria-label="Settings" aria-haspopup="true" aria-expanded="false" aria-controls="settings-menu">
|
||||||
<i class="fa fa-paint-brush"></i>
|
<i class="fa fa-cog"></i>
|
||||||
</button>
|
</button>
|
||||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
<form hidden id="settings-menu" aria-label="Settings" role="menu"></form>
|
||||||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
|
||||||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
|
||||||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|
||||||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|
||||||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|
||||||
</ul>
|
|
||||||
{{#if search_enabled}}
|
{{#if search_enabled}}
|
||||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
<button id="search-toggle" class="icon-button" type="button" title="Search" aria-label="Toggle Searchbar" aria-expanded="false" aria-controls="searchbar">
|
||||||
<i class="fa fa-search"></i>
|
<i class="fa fa-search"></i>
|
||||||
</button>
|
</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -189,13 +183,13 @@
|
||||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
<!-- Mobile navigation buttons -->
|
<!-- Mobile navigation buttons -->
|
||||||
{{#previous}}
|
{{#previous}}
|
||||||
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter">
|
||||||
<i class="fa fa-angle-left"></i>
|
<i class="fa fa-angle-left"></i>
|
||||||
</a>
|
</a>
|
||||||
{{/previous}}
|
{{/previous}}
|
||||||
|
|
||||||
{{#next}}
|
{{#next}}
|
||||||
<a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
<a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter">
|
||||||
<i class="fa fa-angle-right"></i>
|
<i class="fa fa-angle-right"></i>
|
||||||
</a>
|
</a>
|
||||||
{{/next}}
|
{{/next}}
|
||||||
|
@ -207,13 +201,13 @@
|
||||||
|
|
||||||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||||
{{#previous}}
|
{{#previous}}
|
||||||
<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter">
|
||||||
<i class="fa fa-angle-left"></i>
|
<i class="fa fa-angle-left"></i>
|
||||||
</a>
|
</a>
|
||||||
{{/previous}}
|
{{/previous}}
|
||||||
|
|
||||||
{{#next}}
|
{{#next}}
|
||||||
<a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
<a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter">
|
||||||
<i class="fa fa-angle-right"></i>
|
<i class="fa fa-angle-right"></i>
|
||||||
</a>
|
</a>
|
||||||
{{/next}}
|
{{/next}}
|
||||||
|
|
|
@ -48,7 +48,6 @@ window.search = window.search || {};
|
||||||
URL_MARK_PARAM = 'highlight',
|
URL_MARK_PARAM = 'highlight',
|
||||||
teaser_count = 0,
|
teaser_count = 0,
|
||||||
|
|
||||||
SEARCH_HOTKEY_KEYCODE = 83,
|
|
||||||
ESCAPE_KEYCODE = 27,
|
ESCAPE_KEYCODE = 27,
|
||||||
DOWN_KEYCODE = 40,
|
DOWN_KEYCODE = 40,
|
||||||
UP_KEYCODE = 38,
|
UP_KEYCODE = 38,
|
||||||
|
@ -325,14 +324,10 @@ window.search = window.search || {};
|
||||||
(searchbar.value.trim() !== "") ? "push" : "replace");
|
(searchbar.value.trim() !== "") ? "push" : "replace");
|
||||||
if (hasFocus()) {
|
if (hasFocus()) {
|
||||||
unfocusSearchbar();
|
unfocusSearchbar();
|
||||||
|
searchicon.focus();
|
||||||
}
|
}
|
||||||
showSearch(false);
|
showSearch(false);
|
||||||
marker.unmark();
|
marker.unmark();
|
||||||
} else if (!hasFocus() && e.keyCode === SEARCH_HOTKEY_KEYCODE) {
|
|
||||||
e.preventDefault();
|
|
||||||
showSearch(true);
|
|
||||||
window.scrollTo(0, 0);
|
|
||||||
searchbar.select();
|
|
||||||
} else if (hasFocus() && e.keyCode === DOWN_KEYCODE) {
|
} else if (hasFocus() && e.keyCode === DOWN_KEYCODE) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
unfocusSearchbar();
|
unfocusSearchbar();
|
||||||
|
|
Loading…
Reference in New Issue