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 %}