New Commit: Unify reader modal open/close behavior Refactors reader modal handling into shared global open/close functions for TOC, vocabulary, license, and chapter citation dialogs. Modals now consistently toggle both `hidden` and `display` state, close on backdrop click, and support a global Escape shortcut that also hides the settings panel. Template markup was updated to call the new close handlers directly, and a reusable `.hidden` utility class was added in reader CSS.
Repository: Hestenb62/_legacy_backup
Author: Hesten Berger
Commit Message: Unify reader modal open/close behavior Refactors reader modal handling into shared global open/close functions for TOC, vocabulary, license, and chapter citation dialogs. Modals now consistently toggle both and state, close on backdrop click, and support a global Escape shortcut that also hides the settings panel. Template markup was updated to call the new close handlers directly, and a reusable utility class was added in reader CSS.
URL: https://github.com/Hestenb62/_legacy_backup/commit/0d76ca746ffa77a61a320f0ad70e8581bdce5a7d
Code Changes:
diff --git a/library/read/reader.css b/library/read/reader.css
index 7351457..9e0e2ab 100644
--- a/library/read/reader.css
+++ b/library/read/reader.css
@@ -7,6 +7,11 @@
@import url('https://fonts.cdnfonts.com/css/open-dyslexic');
@import url('https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,300;0,400;0,700;1,300;1,400&display=swap');
+/* Utility Classes */
+.hidden {
+ display: none !important;
+}
+
/* ==========================================================================
1. Reader Typography & Accessibility Font Classes
========================================================================== */
diff --git a/library/read/reader.js b/library/read/reader.js
index c0870fa..a69273b 100644
--- a/library/read/reader.js
+++ b/library/read/reader.js
@@ -645,55 +645,116 @@
6. Modals & Drawers (TOC, Vocab, License)
========================================================================== */
function initModalsAndDrawers() {
- // TOC Drawer
- const openTocBtn = document.getElementById("open-toc-modal");
const tocModal = document.getElementById("toc-modal");
- const closeTocBtn = document.getElementById("close-toc-modal");
+ const vocabModal = document.getElementById("vocab-modal");
+ const licenseModal = document.getElementById("license-modal");
+ const citeModal = document.getElementById("chapterCitationModal");
+ const settingsPanel = document.getElementById("settings-panel");
- if (openTocBtn && tocModal) {
- openTocBtn.addEventListener("click", () => tocModal.classList.remove("hidden"));
- }
- if (closeTocBtn && tocModal) {
- closeTocBtn.addEventListener("click", () => tocModal.classList.add("hidden"));
- }
+ window.openTocModal = function () {
+ if (tocModal) {
+ tocModal.classList.remove("hidden");
+ tocModal.style.display = "flex";
+ }
+ };
+
+ window.closeTocModal = function () {
+ if (tocModal) {
+ tocModal.classList.add("hidden");
+ tocModal.style.display = "none";
+ }
+ };
+
+ window.openVocabModal = function () {
+ if (vocabModal) {
+ vocabModal.classList.remove("hidden");
+ vocabModal.style.display = "flex";
+ }
+ };
+
+ window.closeVocabModal = function () {
+ if (vocabModal) {
+ vocabModal.classList.add("hidden");
+ vocabModal.style.display = "none";
+ }
+ };
+
+ window.openLicenseModal = function () {
+ if (licenseModal) {
+ licenseModal.classList.remove("hidden");
+ licenseModal.style.display = "flex";
+ }
+ };
+
+ window.closeLicenseModal = function () {
+ if (licenseModal) {
+ licenseModal.classList.add("hidden");
+ licenseModal.style.display = "none";
+ }
+ };
+
+ window.openChapterCitationModal = function () {
+ if (citeModal) {
+ renderReaderCitation(window.BOOK_METADATA || {});
+ citeModal.classList.remove("hidden");
+ citeModal.style.display = "flex";
+ }
+ };
+
+ window.closeChapterCitationModal = function () {
+ if (citeModal) {
+ citeModal.classList.add("hidden");
+ citeModal.style.display = "none";
+ }
+ };
+
+ // DOM Click bindings
+ const openTocBtn = document.getElementById("open-toc-modal");
+ const closeTocBtn = document.getElementById("close-toc-modal");
+ if (openTocBtn) openTocBtn.addEventListener("click", window.openTocModal);
+ if (closeTocBtn) closeTocBtn.addEventListener("click", window.closeTocModal);
if (tocModal) {
tocModal.addEventListener("click", (e) => {
- if (e.target === tocModal) tocModal.classList.add("hidden");
+ if (e.target === tocModal) window.closeTocModal();
});
}
- // Vocab & Study Guide Modal
const openVocabBtn = document.getElementById("open-vocab-btn");
- const vocabModal = document.getElementById("vocab-modal");
const closeVocabBtn = document.getElementById("close-vocab-modal");
-
- if (openVocabBtn && vocabModal) {
- openVocabBtn.addEventListener("click", () => vocabModal.classList.remove("hidden"));
- }
- if (closeVocabBtn && vocabModal) {
- closeVocabBtn.addEventListener("click", () => vocabModal.classList.add("hidden"));
- }
+ if (openVocabBtn) openVocabBtn.addEventListener("click", window.openVocabModal);
+ if (closeVocabBtn) closeVocabBtn.addEventListener("click", window.closeVocabModal);
if (vocabModal) {
vocabModal.addEventListener("click", (e) => {
- if (e.target === vocabModal) vocabModal.classList.add("hidden");
+ if (e.target === vocabModal) window.closeVocabModal();
});
}
- // License Modal
const closeLicenseBtn = document.getElementById("close-license-modal");
- const licenseModal = document.getElementById("license-modal");
-
- window.openLicenseModal = function () {
- if (licenseModal) licenseModal.classList.remove("hidden");
- };
- if (closeLicenseBtn && licenseModal) {
- closeLicenseBtn.addEventListener("click", () => licenseModal.classList.add("hidden"));
- }
+ if (closeLicenseBtn) closeLicenseBtn.addEventListener("click", window.closeLicenseModal);
if (licenseModal) {
licenseModal.addEventListener("click", (e) => {
- if (e.target === licenseModal) licenseModal.classList.add("hidden");
+ if (e.target === licenseModal) window.closeLicenseModal();
+ });
+ }
+
+ const closeCiteBtn = document.getElementById("close-chapter-cite-modal");
+ if (closeCiteBtn) closeCiteBtn.addEventListener("click", window.closeChapterCitationModal);
+ if (citeModal) {
+ citeModal.addEventListener("click", (e) => {
+ if (e.target === citeModal) window.closeChapterCitationModal();
});
}
+
+ // Global ESC key to close all modals & panels
+ document.addEventListener("keydown", (e) => {
+ if (e.key === "Escape") {
+ window.closeTocModal();
+ window.closeVocabModal();
+ window.closeLicenseModal();
+ window.closeChapterCitationModal();
+ if (settingsPanel) settingsPanel.classList.add("hidden");
+ }
+ });
}
/* ==========================================================================
@@ -702,24 +763,7 @@
let readerCitationStyle = 'mla';
function initChapterCitationGenerator(meta) {
- window.openChapterCitationModal = function () {
- const m = document.getElementById("chapterCitationModal");
- if (m) {
- renderReaderCitation(meta);
- m.classList.remove("hidden");
- }
- };
-
- const closeBtn = document.getElementById("close-chapter-cite-modal");
- const modal = document.getElementById("chapterCitationModal");
- if (closeBtn && modal) {
- closeBtn.addEventListener("click", () => modal.classList.add("hidden"));
- }
- if (modal) {
- modal.addEventListener("click", (e) => {
- if (e.target === modal) modal.classList.add("hidden");
- });
- }
+ // Initialized in initModalsAndDrawers
}
window.switchReaderCitationStyle = function (style) {
diff --git a/library/read/reader_template.php b/library/read/reader_template.php
index c1f7f99..70efb2e 100644
--- a/library/read/reader_template.php
+++ b/library/read/reader_template.php
@@ -356,11 +356,11 @@ include ABSPATH . 'src/header.php';
<!-- Table of Contents Slide-Out Modal -->
<?php if ($totalChapters > 1): ?>
- <div id="toc-modal" class="toc-modal-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="toc-title">
- <div class="toc-content">
+ <div id="toc-modal" class="toc-modal-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="toc-title" onclick="closeTocModal()">
+ <div class="toc-content" onclick="event.stopPropagation()">
<div class="toc-header">
<h2 id="toc-title">Table of Contents</h2>
- <button type="button" class="toc-close" id="close-toc-modal" aria-label="Close Table of Contents">×</button>
+ <button type="button" class="toc-close" id="close-toc-modal" onclick="closeTocModal()" aria-label="Close Table of Contents">×</button>
</div>
<div class="toc-grid">
<?php for ($i = 1; $i <= $totalChapters; $i++):
@@ -382,8 +382,8 @@ include ABSPATH . 'src/header.php';
<?php endif; ?>
<!-- Sourcing & Info Modal -->
-<div id="license-modal" class="modal-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="license-title">
- <div class="modal-card license-modal-card">
+<div id="license-modal" class="modal-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="license-title" onclick="closeLicenseModal()">
+ <div class="modal-card license-modal-card" onclick="event.stopPropagation()">
<div class="modal-card-header">
<div class="modal-card-title">
<div class="modal-icon-circle">
@@ -394,7 +394,7 @@ include ABSPATH . 'src/header.php';
<p class="modal-subtitle">Metadata, License & Primary Sources</p>
</div>
</div>
- <button type="button" id="close-license-modal" class="modal-card-close-btn" aria-label="Close license info">
+ <button type="button" id="close-license-modal" class="modal-card-close-btn" onclick="closeLicenseModal()" aria-label="Close license info">
<i class="fas fa-times"></i>
</button>
</div>
@@ -416,8 +416,8 @@ include ABSPATH . 'src/header.php';
</div>
<!-- Chapter Citation Modal -->
-<div id="chapterCitationModal" class="modal-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="chapter-cite-title">
- <div class="modal-card citation-modal-card">
+<div id="chapterCitationModal" class="modal-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="chapter-cite-title" onclick="closeChapterCitationModal()">
+ <div class="modal-card citation-modal-card" onclick="event.stopPropagation()">
<div class="modal-card-header">
<div class="modal-card-title">
<div class="modal-icon-circle">
@@ -428,7 +428,7 @@ include ABSPATH . 'src/header.php';
<p class="modal-subtitle">Academic formats for citations & bibliography</p>
</div>
</div>
- <button type="button" id="close-chapter-cite-modal" class="modal-card-close-btn" aria-label="Close citation modal">
+ <button type="button" id="close-chapter-cite-modal" class="modal-card-close-btn" onclick="closeChapterCitationModal()" aria-label="Close citation modal">
<i class="fas fa-times"></i>
</button>
</div>