diff --git a/app/static/js/custom_scrollbar.js b/app/static/js/container.js similarity index 100% rename from app/static/js/custom_scrollbar.js rename to app/static/js/container.js diff --git a/app/static/js/fullscreen.js b/app/static/js/fullscreen.js new file mode 100644 index 0000000..ecf348b --- /dev/null +++ b/app/static/js/fullscreen.js @@ -0,0 +1,83 @@ +/** + * Add or remove the `fullscreen=1` URL parameter. + * @param {boolean} enabled + */ +function updateUrlFullscreen(enabled) { + var url = new URL(window.location); + if (enabled) url.searchParams.set('fullscreen', '1'); + else url.searchParams.delete('fullscreen'); + window.history.replaceState({}, '', url); +} + +/** + * Enter fullscreen: hide header/footer, enable full width, recalc scroll, + * set both URL params, update button. + */ +function enterFullscreen() { + document.querySelectorAll('header, footer') + .forEach(function(el){ el.style.display = 'none'; }); + setFullWidth(true); + updateUrlFullscreen(true); + + if (typeof adjustScrollContainerHeight === 'function') adjustScrollContainerHeight(); + if (typeof updateCustomScrollbar === 'function') updateCustomScrollbar(); +} + +/** + * Exit fullscreen: show header/footer, disable full width, recalc scroll, + * clear both URL params, update button. + */ +function exitFullscreen() { + document.querySelectorAll('header, footer') + .forEach(function(el){ el.style.display = ''; }); + setFullWidth(false); + updateUrlFullscreen(false); + + if (typeof adjustScrollContainerHeight === 'function') adjustScrollContainerHeight(); + if (typeof updateCustomScrollbar === 'function') updateCustomScrollbar(); + if (typeof syncIframeHeight === 'function') syncIframeHeight(); +} + +/** + * Toggle between enter and exit fullscreen. + */ +function toggleFullscreen() { + if (document.fullscreenElement) exitFullscreen(); + else enterFullscreen(); +} + +/** + * Read `fullscreen` flag from URL on load. + * @returns {boolean} + */ +function initFullscreenFromUrl() { + return new URLSearchParams(window.location.search).get('fullscreen') === '1'; +} + +// On page load: apply fullwidth & fullscreen flags +window.addEventListener('DOMContentLoaded', function() { + // first fullwidth + var wasFullWidth = initFullWidthFromUrl(); + setFullWidth(wasFullWidth); + + // now fullscreen + if (initFullscreenFromUrl()) { + enterFullscreen(); + } +}); + +// Mirror native F11/fullscreen API events +document.addEventListener('fullscreenchange', function() { + if (document.fullscreenElement) enterFullscreen(); + else exitFullscreen(); +}); +window.addEventListener('resize', function() { + var isUiFs = Math.abs(window.innerHeight - screen.height) < 2; + if (isUiFs) enterFullscreen(); + else exitFullscreen(); +}); + +// Expose globally +window.fullscreen = enterFullscreen; +window.exitFullscreen = exitFullscreen; +window.toggleFullscreen = toggleFullscreen; diff --git a/app/static/js/fullwidth.js b/app/static/js/fullwidth.js new file mode 100644 index 0000000..06105e4 --- /dev/null +++ b/app/static/js/fullwidth.js @@ -0,0 +1,42 @@ +/** + * Toggles the .container class between .container and .container-fluid. + * @param {boolean} enabled – true = full width, false = normal. + */ +function setFullWidth(enabled) { + var el = document.querySelector('.container, .container-fluid'); + if (!el) return; + console.log(el) + if (enabled) { + el.classList.replace('container', 'container-fluid'); + updateUrlFullWidth(true) + } else { + el.classList.replace('container-fluid', 'container'); + updateUrlFullWidth(false) + } +} + +/** + * Reads the URL parameter `fullwidth` and applies full width if it's set. + * @returns {boolean} – current full‐width state + */ +function initFullWidthFromUrl() { + var isFull = new URLSearchParams(window.location.search).get('fullwidth') === '1'; + setFullWidth(isFull); + return isFull; +} + +/** + * Adds or removes the `fullwidth=1` URL parameter. + * @param {boolean} enabled + */ +function updateUrlFullWidth(enabled) { + var url = new URL(window.location); + if (enabled) url.searchParams.set('fullwidth', '1'); + else url.searchParams.delete('fullwidth'); + window.history.replaceState({}, '', url); +} + +// Expose globally +window.setFullWidth = setFullWidth; +window.initFullWidthFromUrl = initFullWidthFromUrl; +window.updateUrlFullWidth = updateUrlFullWidth; diff --git a/app/static/js/iframe.js b/app/static/js/iframe.js index a983573..c044c0b 100644 --- a/app/static/js/iframe.js +++ b/app/static/js/iframe.js @@ -106,6 +106,7 @@ document.addEventListener("DOMContentLoaded", function() { link.addEventListener("click", function(event) { event.preventDefault(); // prevent full page navigation openIframe(this.href); + updateUrlFullWidth(true); }); }); diff --git a/app/static/js/screen.js b/app/static/js/screen.js deleted file mode 100644 index a20b0c6..0000000 --- a/app/static/js/screen.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * screen.js - * Provides fullscreen and exitFullscreen functionality: - * - fullscreen(): hides header/footer, expands container, recalculates main height, sets ?fullscreen=1 - * - exitFullscreen(): restores header/footer, container, recalculates main height, removes parameter - * - toggleFullscreen(): toggles based on current state - * - updateButtonIcon(): updates a button's icon/text based on fullscreen state - * Reacts to URL ?fullscreen=1 on page load - * Mirrors browser fullscreen (F11) via fullscreenchange and resize events - */ - -// Update the toggle button's icon/text -function updateButtonIcon() { - const btn = document.getElementById('fullscreen-btn'); - if (!btn) return; - if (document.fullscreenElement) { - btn.innerHTML = ''; - btn.title = 'Exit Fullscreen'; - } else { - btn.innerHTML = ''; - btn.title = 'Enter Fullscreen'; - } -} - -async function fullscreen() { - // Hide header and footer - document.querySelectorAll('header, footer').forEach(el => el && (el.style.display = 'none')); - // Expand container to full width - const container = document.querySelector('.container'); - if (container && !container.classList.contains('container-fluid')) { - container.classList.replace('container', 'container-fluid'); - } - // Recalculate main height (guarded) - if (typeof adjustScrollContainerHeight === 'function') { - try { adjustScrollContainerHeight(); } catch (e) { console.warn('adjustScrollContainerHeight failed:', e); } - } - if (typeof updateCustomScrollbar === 'function') { - try { updateCustomScrollbar(); } catch (e) { console.warn('updateCustomScrollbar failed:', e); } - } - // Update URL parameter - const url = new URL(window.location); - url.searchParams.set('fullscreen', '1'); - window.history.replaceState({}, '', url); - // Update toggle button - updateButtonIcon(); -} - -function exitFullscreen() { - // Show header and footer - document.querySelectorAll('header, footer').forEach(el => el && (el.style.display = '')); - // Revert container to default width - const container = document.querySelector('.container-fluid'); - if (container) container.classList.replace('container-fluid', 'container'); - // Recalculate main height (guarded) - if (typeof adjustScrollContainerHeight === 'function') { - try { adjustScrollContainerHeight(); } catch (e) { console.warn('adjustScrollContainerHeight failed:', e); } - } - if (typeof updateCustomScrollbar === 'function') { - try { updateCustomScrollbar(); } catch (e) { console.warn('updateCustomScrollbar failed:', e); } - } - if (typeof syncIframeHeight === 'function') { - try { syncIframeHeight(); } catch (e) { console.warn('syncIframeHeight failed:', e); } - } - // Remove URL parameter - const url = new URL(window.location); - url.searchParams.delete('fullscreen'); - window.history.replaceState({}, '', url); - // Update toggle button - updateButtonIcon(); -} - -function toggleFullscreen() { - if (document.fullscreenElement) exitFullscreen(); - else fullscreen(); -} - -// On load: check URL param and set state -window.addEventListener('DOMContentLoaded', () => { - const params = new URLSearchParams(window.location.search); - if (params.get('fullscreen') === '1') fullscreen(); - else updateButtonIcon(); -}); - -function isAnyBrowserFullscreen() { - // Fullscreen API - const apiFs = !!( - document.fullscreenElement || - document.webkitFullscreenElement || - document.mozFullScreenElement || - document.msFullscreenElement - ); - - // Browser-chrome F11 fullscreen - const uiFs = Math.abs(window.innerHeight - screen.height) < 2; - - // PWA fullscreen - const pwaFs = window.matchMedia('(display-mode: fullscreen)').matches; - - return apiFs || uiFs || pwaFs; -} - -// 1) Fullscreen API change (for JS-driven requestFullscreen) -document.addEventListener('fullscreenchange', () => { - if (isAnyBrowserFullscreen()) fullscreen(); - else exitFullscreen(); -}); - -// 2) Chromium F11 fallback -window.addEventListener('resize', () => { - if (isAnyBrowserFullscreen()) fullscreen(); - else exitFullscreen(); -}); - -// Expose functions globally -window.fullscreen = fullscreen; -window.exitFullscreen = exitFullscreen; -window.toggleFullscreen = toggleFullscreen; -window.updateButtonIcon = updateButtonIcon; diff --git a/app/templates/moduls/base.html.j2 b/app/templates/moduls/base.html.j2 index 10932cd..c51437c 100644 --- a/app/templates/moduls/base.html.j2 +++ b/app/templates/moduls/base.html.j2 @@ -49,11 +49,16 @@ {% include "moduls/modal.html.j2" %} - - - - - - + {% for name in [ + 'modal', + 'navigation', + 'tooltip', + 'container', + 'fullwidth', + 'fullscreen', + 'iframe', + ] %} + + {% endfor %} \ No newline at end of file diff --git a/app/templates/moduls/navigation.html.j2 b/app/templates/moduls/navigation.html.j2 index 6c2e6d4..2b90ff4 100644 --- a/app/templates/moduls/navigation.html.j2 +++ b/app/templates/moduls/navigation.html.j2 @@ -36,37 +36,35 @@