From a42e8d29073d442a07955104538512f471b28cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Gla=CC=88ser?= Date: Mon, 15 Jun 2026 11:30:26 +0200 Subject: [PATCH] Add root login compatibility wrappers --- assets/help-icon-overlays.js | 129 +++++++++++++++++++ assets/styles.css | 1 + docs/legacy/temporary_migration_artifacts.md | 16 +++ index.php | 4 + logout.php | 4 + 5 files changed, 154 insertions(+) create mode 100644 assets/help-icon-overlays.js create mode 100644 assets/styles.css create mode 100644 docs/legacy/temporary_migration_artifacts.md create mode 100644 index.php create mode 100644 logout.php diff --git a/assets/help-icon-overlays.js b/assets/help-icon-overlays.js new file mode 100644 index 0000000..84edff9 --- /dev/null +++ b/assets/help-icon-overlays.js @@ -0,0 +1,129 @@ +(function initHelpIconOverlayModule() { + const CLOSE_HANDLERS = { + '.sg-pulldown-demo': (root) => { + root.querySelectorAll('.sg-pulldown-demo').forEach((demo) => { + const trigger = demo.querySelector('.sg-pulldown-demo__trigger'); + demo.dataset.open = 'false'; + if (trigger) { + trigger.setAttribute('aria-expanded', 'false'); + } + }); + }, + '.sg-sandwich-menu-wrap': (root) => { + root.querySelectorAll('.sg-sandwich-menu-wrap').forEach((wrap) => { + const button = wrap.querySelector('.sg-sandwich-button'); + wrap.dataset.open = 'false'; + if (button) { + button.setAttribute('aria-expanded', 'false'); + } + }); + }, + }; + + const getViewportWidth = () => { + if (window.visualViewport && typeof window.visualViewport.width === 'number') { + return window.visualViewport.width; + } + return window.innerWidth; + }; + + const getSafeInsetPx = () => { + const rootStyles = getComputedStyle(document.documentElement); + const spacingSmallRaw = rootStyles.getPropertyValue('--spacing-small').trim(); + const rootFontSize = parseFloat(rootStyles.fontSize) || 16; + const spacingSmallValue = parseFloat(spacingSmallRaw); + if (Number.isNaN(spacingSmallValue)) { + return 0; + } + if (spacingSmallRaw.endsWith('rem')) { + return spacingSmallValue * rootFontSize; + } + return spacingSmallValue; + }; + + const closeAllHelpIcons = (root) => { + root.querySelectorAll('.sg-help-icon-wrap').forEach((wrap) => { + const button = wrap.querySelector('.sg-help-icon'); + const panel = wrap.querySelector('.sg-help-icon-panel'); + wrap.dataset.open = 'false'; + if (panel) { + panel.style.removeProperty('transform'); + } + if (button) { + button.setAttribute('aria-expanded', 'false'); + } + }); + }; + + window.sgInitHelpIconOverlays = (options = {}) => { + const root = options.root || document; + const closeOnOpenSelectors = options.closeOnOpenSelectors || []; + const outsideClickIgnoreSelectors = options.outsideClickIgnoreSelectors || []; + + root.querySelectorAll('.sg-help-icon-wrap').forEach((wrap) => { + if (wrap.dataset.helpIconInit === 'true') { + return; + } + wrap.dataset.helpIconInit = 'true'; + + const button = wrap.querySelector('.sg-help-icon'); + const panel = wrap.querySelector('.sg-help-icon-panel'); + if (!button || !panel) { + return; + } + + button.addEventListener('click', (event) => { + event.stopPropagation(); + const nextState = wrap.dataset.open !== 'true'; + + closeAllHelpIcons(root); + closeOnOpenSelectors.forEach((selector) => { + const handler = CLOSE_HANDLERS[selector]; + if (handler) { + handler(root); + } + }); + + if (!nextState) { + return; + } + + wrap.dataset.align = 'left'; + wrap.dataset.open = 'true'; + button.setAttribute('aria-expanded', 'true'); + + const viewportWidth = getViewportWidth(); + const panelRect = panel.getBoundingClientRect(); + if (panelRect.right > viewportWidth) { + wrap.dataset.align = 'right'; + } + const alignedPanelRect = panel.getBoundingClientRect(); + if (alignedPanelRect.left < 0) { + wrap.dataset.align = 'left'; + } + + const clampedRect = panel.getBoundingClientRect(); + const safeInset = getSafeInsetPx(); + let shiftX = 0; + if (clampedRect.right > (viewportWidth - safeInset)) { + shiftX -= clampedRect.right - (viewportWidth - safeInset); + } + if ((clampedRect.left + shiftX) < safeInset) { + shiftX += safeInset - (clampedRect.left + shiftX); + } + if (shiftX !== 0) { + panel.style.transform = `translateX(${shiftX}px)`; + } + }); + }); + + document.addEventListener('click', (event) => { + const isInsideIgnoredZone = ['.sg-help-icon-wrap', ...outsideClickIgnoreSelectors] + .some((selector) => event.target.closest(selector)); + if (isInsideIgnoredZone) { + return; + } + closeAllHelpIcons(root); + }); + }; +})(); diff --git a/assets/styles.css b/assets/styles.css new file mode 100644 index 0000000..8f2ad9a --- /dev/null +++ b/assets/styles.css @@ -0,0 +1 @@ +@import url("/public/assets/styles.css"); diff --git a/docs/legacy/temporary_migration_artifacts.md b/docs/legacy/temporary_migration_artifacts.md new file mode 100644 index 0000000..3fca643 --- /dev/null +++ b/docs/legacy/temporary_migration_artifacts.md @@ -0,0 +1,16 @@ +# Temporary Migration Artifacts + +Stand: 2026-06-15 + +Diese Artefakte sind eine minimale Kompatibilitaetsschicht, damit die Applikation auch dann unter dem aktuellen Webroot laeuft, wenn der Server noch nicht sauber auf `public/` zeigt. + +## Aktuell vorhanden + +- Root-`index.php` als Delegation auf `public/index.php` +- Root-`logout.php` als Delegation auf `public/logout.php` +- Root-`assets/styles.css` als Import auf `public/assets/styles.css` +- Root-`assets/help-icon-overlays.js` als Kopie des vorhandenen Helferskripts + +## Rueckbau + +Sobald der Webroot sauber auf `public/` zeigt, koennen diese Wrapper wieder entfernt werden. diff --git a/index.php b/index.php new file mode 100644 index 0000000..1dbc5f5 --- /dev/null +++ b/index.php @@ -0,0 +1,4 @@ +