Add quiz mode toggle to chapter/section toolbar

Adds a button to the existing top-right button group on chapter and
section pages that hides everything outside of the breadcrumb, the
heading, the rendered questions and the link to the next section or
chapter at the end of the page. The state is persisted via
localStorage so it survives navigation. On pages without questions a
small notice is shown instead.

Replaces the previously published userscript by integrating the same
behaviour directly into the site.
This commit is contained in:
Dennis Eisold
2026-04-30 22:11:55 +02:00
parent 39b4b0769f
commit 4d08c3db55
4 changed files with 126 additions and 2 deletions
+82
View File
@@ -9,6 +9,7 @@ document.addEventListener("DOMContentLoaded", function() {
for (var i = 0; i < els.length; i++) { for (var i = 0; i < els.length; i++) {
shuffleChildren(els[i]); shuffleChildren(els[i]);
} }
initQuizMode();
}); });
function answer(el, correct) { function answer(el, correct) {
@@ -18,6 +19,87 @@ function answer(el, correct) {
el.classList.add("wrong") el.classList.add("wrong")
} }
(function () {
var NOTICE_ID = "quiz-mode-notice";
var STORAGE_KEY = "quiz-mode-enabled";
var QUIZ_CLASS = "quiz-mode-active";
var HAS_Q_CLASS = "quiz-has-questions";
function pageHasQuestions() {
return document.querySelector(".course .question") !== null;
}
function tagSectionTail() {
var course = document.querySelector(".course");
if (!course) return false;
var tagged = course.querySelectorAll("[data-quiz-tail]");
for (var i = 0; i < tagged.length; i++) {
tagged[i].removeAttribute("data-quiz-tail");
}
var children = course.children;
for (var j = 0; j < children.length; j++) {
var child = children[j];
if (child.tagName !== "DIV") continue;
var text = (child.textContent || "").toLowerCase();
if (text.indexOf("weiter zum nächsten abschnitt") !== -1 ||
text.indexOf("weiter zum nächsten kapitel") !== -1) {
child.setAttribute("data-quiz-tail", "");
return true;
}
}
return false;
}
function showNotice(text) {
var n = document.getElementById(NOTICE_ID);
if (!n) {
n = document.createElement("div");
n.id = NOTICE_ID;
document.body.appendChild(n);
}
n.textContent = text;
}
function hideNotice() {
var n = document.getElementById(NOTICE_ID);
if (n) n.parentNode.removeChild(n);
}
function updateButton(btn, on) {
btn.setAttribute("aria-pressed", on ? "true" : "false");
btn.classList.toggle("active", on);
btn.title = on ? "Alles anzeigen" : "Nur Fragen anzeigen";
}
function setQuizMode(on) {
var hasQ = pageHasQuestions();
document.body.classList.toggle(HAS_Q_CLASS, hasQ);
if (on && hasQ) tagSectionTail();
document.body.classList.toggle(QUIZ_CLASS, on);
var btn = document.getElementById("quiz-mode-toggle");
if (btn) updateButton(btn, on);
if (on && !hasQ) {
showNotice("Keine Fragen auf dieser Seite gefunden.");
} else {
hideNotice();
}
}
window.initQuizMode = function () {
var btn = document.getElementById("quiz-mode-toggle");
if (!btn) return;
btn.addEventListener("click", function () {
var next = !document.body.classList.contains(QUIZ_CLASS);
setQuizMode(next);
try { localStorage.setItem(STORAGE_KEY, next ? "1" : "0"); } catch (e) {}
});
var initial = false;
try { initial = localStorage.getItem(STORAGE_KEY) === "1"; } catch (e) {}
if (initial) setQuizMode(true);
else updateButton(btn, false);
};
})();
/* /*
var els = document.querySelectorAll(".question .question-text"); var els = document.querySelectorAll(".question .question-text");
+40
View File
@@ -446,3 +446,43 @@ span.formula {
.course .katex-display { .course .katex-display {
margin: 1em 0em; margin: 1em 0em;
} }
/* Quiz-Modus */
#quiz-mode-toggle {
cursor: pointer;
}
#quiz-mode-toggle.active {
background: #0a7a2a;
border-color: #0a7a2a;
color: #fff;
}
#quiz-mode-toggle.active svg {
fill: #fff;
}
#quiz-mode-notice {
position: fixed;
top: 12px;
right: 12px;
z-index: 99999;
max-width: 260px;
padding: 8px 12px;
font: 500 13px/1.35 system-ui, -apple-system, sans-serif;
color: #333;
background: #fff3cd;
border: 1px solid #ffe69c;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
body.quiz-mode-active.quiz-has-questions .course > * {
display: none !important;
}
body.quiz-mode-active.quiz-has-questions .course > .course-toolbar,
body.quiz-mode-active.quiz-has-questions .course > h1,
body.quiz-mode-active.quiz-has-questions .course > nav,
body.quiz-mode-active.quiz-has-questions .course > .question,
body.quiz-mode-active.quiz-has-questions .course > [data-quiz-tail],
body.quiz-mode-active.quiz-has-questions .course > [data-quiz-tail] ~ * {
display: revert !important;
}
+2 -1
View File
@@ -1,10 +1,11 @@
<div style="float: right;"> <div class="course-toolbar" style="float: right;">
<div class="btn-group" role="group"> <div class="btn-group" role="group">
{% if chapter["video_url"] %} {% if chapter["video_url"] %}
<a class="btn btn-secondary" href="{{ chapter["video_url"] }}" title="Video öffnen" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"></path><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"></path></svg></a> <a class="btn btn-secondary" href="{{ chapter["video_url"] }}" title="Video öffnen" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"></path><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"></path></svg></a>
{% endif %} {% endif %}
<a class="btn btn-secondary" href="{{ edition }}_slide_{{ chapter["ident"] }}.html" title="Präsentationsfolien öffnen"><svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M840-120v-640H120v320H40v-320q0-33 23.5-56.5T120-840h720q33 0 56.5 23.5T920-760v560q0 33-23.5 56.5T840-120ZM360-400q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47Zm0-80q33 0 56.5-23.5T440-560q0-33-23.5-56.5T360-640q-33 0-56.5 23.5T280-560q0 33 23.5 56.5T360-480ZM40-80v-112q0-34 17.5-62.5T104-298q62-31 126-46.5T360-360q66 0 130 15.5T616-298q29 15 46.5 43.5T680-192v112H40Zm80-80h480v-32q0-11-5.5-20T580-226q-54-27-109-40.5T360-280q-56 0-111 13.5T140-226q-9 5-14.5 14t-5.5 20v32Zm240-400Zm0 400Z"/></svg></a> <a class="btn btn-secondary" href="{{ edition }}_slide_{{ chapter["ident"] }}.html" title="Präsentationsfolien öffnen"><svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M840-120v-640H120v320H40v-320q0-33 23.5-56.5T120-840h720q33 0 56.5 23.5T920-760v560q0 33-23.5 56.5T840-120ZM360-400q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47Zm0-80q33 0 56.5-23.5T440-560q0-33-23.5-56.5T360-640q-33 0-56.5 23.5T280-560q0 33 23.5 56.5T360-480ZM40-80v-112q0-34 17.5-62.5T104-298q62-31 126-46.5T360-360q66 0 130 15.5T616-298q29 15 46.5 43.5T680-192v112H40Zm80-80h480v-32q0-11-5.5-20T580-226q-54-27-109-40.5T360-280q-56 0-111 13.5T140-226q-9 5-14.5 14t-5.5 20v32Zm240-400Zm0 400Z"/></svg></a>
<a class="btn btn-secondary" target="_blank" href="/hm" title="Hilfsmittel herunterladen"><svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 640 640" fill="#000000"><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M192 112L304 112L304 200C304 239.8 336.2 272 376 272L464 272L464 512C464 520.8 456.8 528 448 528L192 528C183.2 528 176 520.8 176 512L176 128C176 119.2 183.2 112 192 112zM352 131.9L444.1 224L376 224C362.7 224 352 213.3 352 200L352 131.9zM192 64C156.7 64 128 92.7 128 128L128 512C128 547.3 156.7 576 192 576L448 576C483.3 576 512 547.3 512 512L512 250.5C512 233.5 505.3 217.2 493.3 205.2L370.7 82.7C358.7 70.7 342.5 64 325.5 64L192 64zM248 320C234.7 320 224 330.7 224 344C224 357.3 234.7 368 248 368L392 368C405.3 368 416 357.3 416 344C416 330.7 405.3 320 392 320L248 320zM248 416C234.7 416 224 426.7 224 440C224 453.3 234.7 464 248 464L392 464C405.3 464 416 453.3 416 440C416 426.7 405.3 416 392 416L248 416z"/></svg></a> <a class="btn btn-secondary" target="_blank" href="/hm" title="Hilfsmittel herunterladen"><svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 640 640" fill="#000000"><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M192 112L304 112L304 200C304 239.8 336.2 272 376 272L464 272L464 512C464 520.8 456.8 528 448 528L192 528C183.2 528 176 520.8 176 512L176 128C176 119.2 183.2 112 192 112zM352 131.9L444.1 224L376 224C362.7 224 352 213.3 352 200L352 131.9zM192 64C156.7 64 128 92.7 128 128L128 512C128 547.3 156.7 576 192 576L448 576C483.3 576 512 547.3 512 512L512 250.5C512 233.5 505.3 217.2 493.3 205.2L370.7 82.7C358.7 70.7 342.5 64 325.5 64L192 64zM248 320C234.7 320 224 330.7 224 344C224 357.3 234.7 368 248 368L392 368C405.3 368 416 357.3 416 344C416 330.7 405.3 320 392 320L248 320zM248 416C234.7 416 224 426.7 224 440C224 453.3 234.7 464 248 464L392 464C405.3 464 416 453.3 416 440C416 426.7 405.3 416 392 416L248 416z"/></svg></a>
<button type="button" class="btn btn-secondary" id="quiz-mode-toggle" title="Nur Fragen anzeigen" aria-pressed="false"><svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 16 16" fill="#000000"><path d="M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 0 0-2.79.588l.77.771A5.944 5.944 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z"/><path d="M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829l.822.822zm-2.943 1.299.822.822a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829z"/><path d="M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709zm10.296 8.884-12-12 .708-.708 12 12-.708.708z"/></svg></button>
</div> </div>
</div> </div>
+2 -1
View File
@@ -1,10 +1,11 @@
<div style="float: right;"> <div class="course-toolbar" style="float: right;">
<div class="btn-group" role="group"> <div class="btn-group" role="group">
{% if section["video_url"] %} {% if section["video_url"] %}
<a class="btn btn-secondary" href="{{ section["video_url"] }}" title="Video öffnen" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"></path><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"></path></svg></a> <a class="btn btn-secondary" href="{{ section["video_url"] }}" title="Video öffnen" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"></path><path d="M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"></path></svg></a>
{% endif %} {% endif %}
<a class="btn btn-secondary" href="{{ edition }}_slide_{{ chapter["ident"] }}.html#{{ section_id }}" title="Präsentationsfolien öffnen"><svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M840-120v-640H120v320H40v-320q0-33 23.5-56.5T120-840h720q33 0 56.5 23.5T920-760v560q0 33-23.5 56.5T840-120ZM360-400q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47Zm0-80q33 0 56.5-23.5T440-560q0-33-23.5-56.5T360-640q-33 0-56.5 23.5T280-560q0 33 23.5 56.5T360-480ZM40-80v-112q0-34 17.5-62.5T104-298q62-31 126-46.5T360-360q66 0 130 15.5T616-298q29 15 46.5 43.5T680-192v112H40Zm80-80h480v-32q0-11-5.5-20T580-226q-54-27-109-40.5T360-280q-56 0-111 13.5T140-226q-9 5-14.5 14t-5.5 20v32Zm240-400Zm0 400Z"/></svg></a> <a class="btn btn-secondary" href="{{ edition }}_slide_{{ chapter["ident"] }}.html#{{ section_id }}" title="Präsentationsfolien öffnen"><svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M840-120v-640H120v320H40v-320q0-33 23.5-56.5T120-840h720q33 0 56.5 23.5T920-760v560q0 33-23.5 56.5T840-120ZM360-400q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47Zm0-80q33 0 56.5-23.5T440-560q0-33-23.5-56.5T360-640q-33 0-56.5 23.5T280-560q0 33 23.5 56.5T360-480ZM40-80v-112q0-34 17.5-62.5T104-298q62-31 126-46.5T360-360q66 0 130 15.5T616-298q29 15 46.5 43.5T680-192v112H40Zm80-80h480v-32q0-11-5.5-20T580-226q-54-27-109-40.5T360-280q-56 0-111 13.5T140-226q-9 5-14.5 14t-5.5 20v32Zm240-400Zm0 400Z"/></svg></a>
<a class="btn btn-secondary" target="_blank" href="/hm" title="Hilfsmittel herunterladen"><svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 640 640" fill="#000000"><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M192 112L304 112L304 200C304 239.8 336.2 272 376 272L464 272L464 512C464 520.8 456.8 528 448 528L192 528C183.2 528 176 520.8 176 512L176 128C176 119.2 183.2 112 192 112zM352 131.9L444.1 224L376 224C362.7 224 352 213.3 352 200L352 131.9zM192 64C156.7 64 128 92.7 128 128L128 512C128 547.3 156.7 576 192 576L448 576C483.3 576 512 547.3 512 512L512 250.5C512 233.5 505.3 217.2 493.3 205.2L370.7 82.7C358.7 70.7 342.5 64 325.5 64L192 64zM248 320C234.7 320 224 330.7 224 344C224 357.3 234.7 368 248 368L392 368C405.3 368 416 357.3 416 344C416 330.7 405.3 320 392 320L248 320zM248 416C234.7 416 224 426.7 224 440C224 453.3 234.7 464 248 464L392 464C405.3 464 416 453.3 416 440C416 426.7 405.3 416 392 416L248 416z"/></svg></a> <a class="btn btn-secondary" target="_blank" href="/hm" title="Hilfsmittel herunterladen"><svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 640 640" fill="#000000"><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M192 112L304 112L304 200C304 239.8 336.2 272 376 272L464 272L464 512C464 520.8 456.8 528 448 528L192 528C183.2 528 176 520.8 176 512L176 128C176 119.2 183.2 112 192 112zM352 131.9L444.1 224L376 224C362.7 224 352 213.3 352 200L352 131.9zM192 64C156.7 64 128 92.7 128 128L128 512C128 547.3 156.7 576 192 576L448 576C483.3 576 512 547.3 512 512L512 250.5C512 233.5 505.3 217.2 493.3 205.2L370.7 82.7C358.7 70.7 342.5 64 325.5 64L192 64zM248 320C234.7 320 224 330.7 224 344C224 357.3 234.7 368 248 368L392 368C405.3 368 416 357.3 416 344C416 330.7 405.3 320 392 320L248 320zM248 416C234.7 416 224 426.7 224 440C224 453.3 234.7 464 248 464L392 464C405.3 464 416 453.3 416 440C416 426.7 405.3 416 392 416L248 416z"/></svg></a>
<button type="button" class="btn btn-secondary" id="quiz-mode-toggle" title="Nur Fragen anzeigen" aria-pressed="false"><svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 16 16" fill="#000000"><path d="M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7.028 7.028 0 0 0-2.79.588l.77.771A5.944 5.944 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.134 13.134 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755-.165.165-.337.328-.517.486l.708.709z"/><path d="M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829l.822.822zm-2.943 1.299.822.822a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829z"/><path d="M3.35 5.47c-.18.16-.353.322-.518.487A13.134 13.134 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7.029 7.029 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709zm10.296 8.884-12-12 .708-.708 12 12-.708.708z"/></svg></button>
</div> </div>
</div> </div>