2025-07-05 18:00:23 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* 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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2025-07-06 18:14:42 +02:00
|
|
|
|
* Starts a requestAnimationFrame loop that calls your recalc methods,
|
|
|
|
|
|
* and stops automatically when the header’s max-height transition ends.
|
2025-07-05 18:00:23 +02:00
|
|
|
|
*/
|
2025-07-06 18:14:42 +02:00
|
|
|
|
function recalcWhileCollapsing() {
|
|
|
|
|
|
const header = document.querySelector('header');
|
|
|
|
|
|
if (!header) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 1) Start the RAF loop
|
|
|
|
|
|
let rafId;
|
|
|
|
|
|
const step = () => {
|
|
|
|
|
|
adjustScrollContainerHeight();
|
|
|
|
|
|
updateCustomScrollbar();
|
|
|
|
|
|
rafId = requestAnimationFrame(step);
|
|
|
|
|
|
};
|
|
|
|
|
|
step();
|
|
|
|
|
|
|
|
|
|
|
|
// 2) Listen for the end of the max-height transition
|
|
|
|
|
|
function onEnd(e) {
|
|
|
|
|
|
if (e.propertyName === 'max-height') {
|
|
|
|
|
|
cancelAnimationFrame(rafId);
|
|
|
|
|
|
header.removeEventListener('transitionend', onEnd);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
header.addEventListener('transitionend', onEnd);
|
|
|
|
|
|
}
|
2025-07-06 17:46:51 +02:00
|
|
|
|
|
2025-07-06 18:14:42 +02:00
|
|
|
|
function enterFullscreen() {
|
|
|
|
|
|
document.body.classList.add('fullscreen');
|
2025-07-05 18:00:23 +02:00
|
|
|
|
setFullWidth(true);
|
|
|
|
|
|
updateUrlFullscreen(true);
|
|
|
|
|
|
|
2025-07-06 18:14:42 +02:00
|
|
|
|
// fade in logo… (unchanged)
|
2025-07-05 18:54:18 +02:00
|
|
|
|
const logo = document.getElementById('navbar_logo');
|
2025-07-06 17:46:51 +02:00
|
|
|
|
if (logo) {
|
2025-07-08 17:16:57 +02:00
|
|
|
|
// hide the navbar‐logo restore link in fullscreen
|
|
|
|
|
|
logo.classList.add('d-none');
|
2025-07-06 17:46:51 +02:00
|
|
|
|
}
|
2025-07-05 18:54:18 +02:00
|
|
|
|
|
2025-07-06 18:14:42 +02:00
|
|
|
|
// now recalc in lock-step with the CSS collapse animation
|
|
|
|
|
|
recalcWhileCollapsing();
|
2025-07-05 18:00:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function exitFullscreen() {
|
2025-07-06 18:14:42 +02:00
|
|
|
|
document.body.classList.remove('fullscreen');
|
|
|
|
|
|
setFullWidth(false);
|
|
|
|
|
|
updateUrlFullscreen(false);
|
2025-07-05 18:00:23 +02:00
|
|
|
|
|
2025-07-05 18:54:18 +02:00
|
|
|
|
const logo = document.getElementById('navbar_logo');
|
2025-07-06 17:46:51 +02:00
|
|
|
|
if (logo) {
|
2025-07-08 17:16:57 +02:00
|
|
|
|
// show the navbar‐logo restore link again
|
|
|
|
|
|
logo.classList.remove('d-none');
|
2025-07-06 17:46:51 +02:00
|
|
|
|
}
|
2025-07-05 18:54:18 +02:00
|
|
|
|
|
2025-07-06 18:14:42 +02:00
|
|
|
|
// recalc while header/footer expand back
|
|
|
|
|
|
recalcWhileCollapsing();
|
2025-07-05 18:00:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Toggle between enter and exit fullscreen.
|
|
|
|
|
|
*/
|
|
|
|
|
|
function toggleFullscreen() {
|
2025-07-05 18:32:26 +02:00
|
|
|
|
const params = new URLSearchParams(window.location.search);
|
|
|
|
|
|
const isFull = params.get('fullscreen') === '1';
|
|
|
|
|
|
|
|
|
|
|
|
if (isFull) exitFullscreen();
|
|
|
|
|
|
else enterFullscreen();
|
2025-07-05 18:00:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 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;
|