(function () {
if (window.passlordForumsEnhancementsBootstrapped) {
return;
}
window.passlordForumsEnhancementsBootstrapped = true;
function storageGet(key) {
try {
return window.localStorage ? window.localStorage.getItem(key) : null;
} catch (error) {
return null;
}
}
function storageSet(key, value) {
try {
if (window.localStorage) {
window.localStorage.setItem(key, value);
}
} catch (error) {
}
}
function clipText(text, maxLength) {
if (!text || text.length <= maxLength) {
return text;
}
return text.slice(0, maxLength).replace(/\s+\S*$/, '') + '...';
}
function markCardAsRead(card, persist) {
var topicKey = card.getAttribute('data-topic-key');
if (!topicKey) {
return;
}
card.classList.add('is-read');
if (persist) {
storageSet('passlord-read-' + topicKey, '1');
}
}
function hydratePreview(card) {
var previewBody = card.querySelector('[data-preview-body]');
var previewPanel = card.querySelector('[data-preview-panel]');
var previewUrl = card.getAttribute('data-preview-url');
var currentState = card.getAttribute('data-preview-state');
if (!previewBody || !previewPanel || !previewUrl || currentState === 'loading' || currentState === 'loaded') {
return;
}
card.setAttribute('data-preview-state', 'loading');
previewPanel.removeAttribute('hidden');
previewBody.textContent = 'Chargement de l\'apercu...';
var request = new XMLHttpRequest();
request.open('GET', previewUrl, true);
request.onreadystatechange = function () {
if (request.readyState !== 4) {
return;
}
var previewText = 'Aucun apercu disponible.';
if (request.status >= 200 && request.status < 300) {
try {
var payload = JSON.parse(request.responseText);
var post = payload && payload.data && payload.data.length ? payload.data[0] : null;
if (post && post.body_raw) {
previewText = clipText(post.body_raw.replace(/\s+/g, ' ').trim(), 220);
}
card.setAttribute('data-preview-state', 'loaded');
} catch (error) {
card.setAttribute('data-preview-state', 'error');
}
} else {
card.setAttribute('data-preview-state', 'error');
}
previewBody.textContent = previewText;
};
request.send(null);
}
function togglePreview(card, forceOpen) {
var previewPanel = card.querySelector('[data-preview-panel]');
if (!previewPanel) {
return;
}
var isOpen = card.getAttribute('data-preview-open') === '1';
var nextState = (typeof forceOpen === 'boolean') ? forceOpen : !isOpen;
if (nextState) {
card.setAttribute('data-preview-open', '1');
previewPanel.removeAttribute('hidden');
hydratePreview(card);
} else {
card.removeAttribute('data-preview-open');
previewPanel.setAttribute('hidden', 'hidden');
}
}
function setupSmartSidebar(sidebar) {
if (!sidebar) {
return;
}
var desktopQuery = window.matchMedia('(min-width: 1080px)');
var edgeGap = 24;
var topGap = 112;
var state = {
lastScrollY: 0,
ticking: false
};
function getScrollY() {
return window.pageYOffset || document.documentElement.scrollTop || 0;
}
function getHeaderOffset() {
var topbarShell = document.querySelector('.forums-topbar-shell');
if (!topbarShell) {
return topGap;
}
var shellRect = topbarShell.getBoundingClientRect();
return Math.max(Math.round(shellRect.bottom + 14), 96);
}
function resetSidebarState() {
sidebar.classList.remove('is-stuck-bottom');
sidebar.style.removeProperty('--forums-sidebar-top');
sidebar.style.removeProperty('--forums-sidebar-bottom-gap');
}
function updateSidebarMode() {
state.ticking = false;
if (!desktopQuery.matches) {
resetSidebarState();
state.lastScrollY = getScrollY();
return;
}
topGap = getHeaderOffset();
var viewportHeight = window.innerHeight || document.documentElement.clientHeight || 1;
var sidebarHeight = sidebar.offsetHeight || 0;
var scrollY = getScrollY();
var delta = scrollY - state.lastScrollY;
var availableHeight = viewportHeight - topGap - edgeGap;
sidebar.style.setProperty('--forums-sidebar-top', topGap + 'px');
sidebar.style.setProperty('--forums-sidebar-bottom-gap', edgeGap + 'px');
if (scrollY <= 0 || sidebarHeight <= availableHeight) {
sidebar.classList.remove('is-stuck-bottom');
} else if (delta > 0) {
sidebar.classList.add('is-stuck-bottom');
} else if (delta < 0) {
sidebar.classList.remove('is-stuck-bottom');
}
state.lastScrollY = scrollY;
}
function queueSidebarModeUpdate() {
if (state.ticking) {
return;
}
state.ticking = true;
window.requestAnimationFrame(updateSidebarMode);
}
function handleViewportChange() {
state.lastScrollY = getScrollY();
queueSidebarModeUpdate();
}
state.lastScrollY = getScrollY();
queueSidebarModeUpdate();
window.addEventListener('scroll', queueSidebarModeUpdate, { passive: true });
window.addEventListener('resize', handleViewportChange);
if (desktopQuery.addEventListener) {
desktopQuery.addEventListener('change', handleViewportChange);
} else if (desktopQuery.addListener) {
desktopQuery.addListener(handleViewportChange);
}
}
document.addEventListener('DOMContentLoaded', function () {
var threadProgressBar = document.querySelector('[data-thread-progress-bar]');
if (threadProgressBar) {
var threadProgressRoot = document.querySelector('[data-thread-progress-root]') || document.body;
var updateThreadProgress = function () {
var rootRect = threadProgressRoot.getBoundingClientRect();
var viewportHeight = window.innerHeight || document.documentElement.clientHeight || 1;
var totalScrollable = Math.max(threadProgressRoot.offsetHeight - viewportHeight * 0.45, 1);
var consumed = Math.min(Math.max((viewportHeight * 0.35) - rootRect.top, 0), totalScrollable);
var ratio = Math.max(0, Math.min(1, consumed / totalScrollable));
threadProgressBar.style.transform = 'scaleX(' + ratio + ')';
};
updateThreadProgress();
window.addEventListener('scroll', updateThreadProgress, { passive: true });
window.addEventListener('resize', updateThreadProgress);
}
var forumsSidebar = document.querySelector('.forums-sidebar');
if (forumsSidebar) {
setupSmartSidebar(forumsSidebar);
}
var cards = document.querySelectorAll('.forum-card[data-topic-key]');
for (var i = 0; i < cards.length; i++) {
(function (card) {
var topicKey = card.getAttribute('data-topic-key');
if (topicKey && storageGet('passlord-read-' + topicKey) === '1') {
card.classList.add('is-read');
}
var links = card.querySelectorAll('a[href]');
for (var linkIndex = 0; linkIndex < links.length; linkIndex++) {
links[linkIndex].addEventListener('click', function () {
markCardAsRead(card, true);
});
}
var previewButton = card.querySelector('[data-preview-toggle]');
if (previewButton) {
previewButton.addEventListener('click', function () {
var shouldOpen = card.getAttribute('data-preview-open') !== '1';
togglePreview(card, shouldOpen);
});
}
// Auto-preview disabled : hover, focus and long-press triggers
// were too intrusive and confused navigation. The preview is
// still accessible explicitly via the "Aperçu rapide" link in
// the card's dropdown menu (handled by previewButton above).
})(cards[i]);
}
});
})();
Erreur interneErreur interne
Une erreur inattendue est survenue. Merci de réessayer plus tard.