From 0b00377103d849618240a34778e7bfa29e4193db Mon Sep 17 00:00:00 2001 From: Sebastian Fischer Date: Sat, 24 Aug 2024 20:13:59 +0200 Subject: [PATCH] [TASK] Refactor frontend resources --- .../flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2 | Bin Resources/Public/JavaScript/sf-books.js | 158 ++++++++++-------- .../Public/Stylesheets/materials-icons.css | 2 +- 3 files changed, 93 insertions(+), 67 deletions(-) rename Resources/Public/{Stylesheets => Fonts}/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2 (100%) diff --git a/Resources/Public/Stylesheets/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2 b/Resources/Public/Fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2 similarity index 100% rename from Resources/Public/Stylesheets/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2 rename to Resources/Public/Fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2 diff --git a/Resources/Public/JavaScript/sf-books.js b/Resources/Public/JavaScript/sf-books.js index 41d3ea5..d899a38 100644 --- a/Resources/Public/JavaScript/sf-books.js +++ b/Resources/Public/JavaScript/sf-books.js @@ -1,87 +1,113 @@ -function getNextSibling(element, selector) { - // Get the next sibling element - let sibling = element.nextElementSibling; - - // If there's no selector, return the first sibling - if (selector) { - // If the sibling matches our selector, use it - // If not, jump to the next sibling and continue the loop - while (sibling) { - if (sibling.matches(selector)) { - break; - } - sibling = sibling.nextElementSibling - } +class EvowebBookAccordion { + /** + * @type {HTMLElement} + */ + current = null; + + constructor() { + this.initializeClickTriggers(); + this.initializeAnchoredAccordion(); } - return sibling; -} - -function emitEvent(element, type) { - let event = document.createEvent('HTMLEvents'); - event.initEvent(type, true, true); - element.dispatchEvent(event); -} + initializeClickTriggers() { + const triggers = [...document.querySelectorAll('.trigger')]; + triggers.map(trigger => trigger.addEventListener('click', event => this.clickEventHandler(event))); + } -function triggerClickHandler(event) { - event.preventDefault(); + initializeAnchoredAccordion() { + if (window.location.hash) { + const hash = window.location.hash, + accordionToOpen = document.querySelector('.trigger' + hash); + if (accordionToOpen) { + this.current = accordionToOpen; + this.activate(this.current); + } + } + } - let trigger = event.target, - current = document.querySelector('.trigger_active'); + /** + * @param {PointerEvent} event + */ + clickEventHandler(event) { + event.preventDefault(); + const trigger = event.target; + + if (trigger === this.current) { + this.deactivate(this.current); + } else { + if (this.current != null) { + this.deactivate(this.current); + } - if (trigger === current) { - current.classList.remove('trigger_active'); - getNextSibling(current, '.toggle_container').classList.add('close'); - } else { - if (current != null ) { - current.classList.remove('trigger_active'); - getNextSibling(current, '.toggle_container').classList.add('close'); + this.current = trigger; + this.activate(this.current); } + } - trigger.classList.add('trigger_active'); - getNextSibling(trigger, '.toggle_container').classList.remove('close'); + /** + * @param {HTMLElement} element + */ + activate(element) { + element.classList.add('trigger_active'); + this.getNextSibling(element, '.toggle_container').classList.remove('close'); } -} -function initAccordion() { - let allTriggers = document.querySelectorAll('.trigger'), - accordionToOpen = null, - keepOpen; + /** + * @param {HTMLElement} element + */ + deactivate(element) { + element.classList.remove('trigger_active'); + this.getNextSibling(element, '.toggle_container').classList.add('close'); + } - allTriggers.forEach(function (trigger) { - trigger.addEventListener('click', triggerClickHandler); - }) + /** + * @param {HTMLElement} element + * @param {string} selector + */ + getNextSibling(element, selector) { + // Get a sibling by selector + return element.parentElement.querySelector(selector); + } +} - if (window.location.hash) { - accordionToOpen = document.querySelector('.trigger' + window.location.hash); +class EvowebBookLetters { + constructor() { + this.initializeClickTriggers(); + } - keepOpen = accordionToOpen != null ? accordionToOpen : allTriggers[0]; - keepOpen.classList.add('trigger_active'); - getNextSibling(keepOpen, '.toggle_container').classList.remove('close'); + initializeClickTriggers() { + const triggers = [...document.querySelectorAll('.tx-sfbooks .letters a')]; + triggers.map(trigger => trigger.addEventListener('click', event => this.clickEventHandler(event))); } -} -function letterClickHandler(event) { - event.preventDefault(); + /** + * @param {PointerEvent} event + */ + clickEventHandler(event) { + event.preventDefault(); - let letter = event.target, - trigger = document.querySelector('.trigger' + letter.hash); + const trigger = event.target, + hash = trigger.hash, + accordionToOpen = document.querySelector('.trigger' + hash); - emitEvent(trigger, 'click'); + this.emitEvent(accordionToOpen, 'click'); - document.body.scrollBy({ top: trigger.top }); - window.location.hash = letter.hash; -} + document.body.scrollBy({ top: accordionToOpen.top }); + window.location.hash = hash; + } -function initLetters() { - let letters = document.querySelectorAll('.tx-sfbooks .letters a'); + emitEvent(element, type) { + element.dispatchEvent(new CustomEvent(type, true, true)); + } +} - letters.forEach(function (letter) { - letter.addEventListener('click', letterClickHandler); - }); +function evowebBookInitialization() { + new EvowebBookAccordion(); + new EvowebBookLetters(); } -document.addEventListener('DOMContentLoaded', function() { - initAccordion(); - initLetters(); -}); +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', evowebBookInitialization); +} else { + evowebBookInitialization(); +} diff --git a/Resources/Public/Stylesheets/materials-icons.css b/Resources/Public/Stylesheets/materials-icons.css index 9adc77d..374d5fe 100644 --- a/Resources/Public/Stylesheets/materials-icons.css +++ b/Resources/Public/Stylesheets/materials-icons.css @@ -3,7 +3,7 @@ font-family: 'Material Icons'; font-style: normal; font-weight: 400; - src: url(./flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2'); + src: url(../Fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2'); } .material-icons {