fix(theme): mirror bounded cookie propagation reconciliation
deploy-preland / deploy zoomstage.online (push) Successful in 39s

This commit is contained in:
Panfilov Konstantin committed 2026-10-21 22:05:02 +03:00
1 parent ad8c8eb849
commit 01933546a7
1 file changed
+19 -1
+19 -1
View File
@@ -44,6 +44,24 @@ $themeSurface = isset($themeSurface) && in_array($themeSurface, ['public', 'priv
return hex.slice(0, 8) + '-' + hex.slice(8, 12) + '-' + hex.slice(12, 16) + '-' + hex.slice(16, 20) + '-' + hex.slice(20); return hex.slice(0, 8) + '-' + hex.slice(8, 12) + '-' + hex.slice(12, 16) + '-' + hex.slice(16, 20) + '-' + hex.slice(20);
} }
function refresh() { const value = read(); apply(value ? themeOf(value) : shown); } function refresh() { const value = read(); apply(value ? themeOf(value) : shown); }
const storageTimers = {soon: null, settled: null, trailing: null};
function refreshAfterStorage() {
refresh();
// Между процессами storage notification может прийти раньше cookie.
// Только повторно читаем authority: event.newValue не задаёт порядок выбора.
const schedule = (slot, delay) => {
storageTimers[slot] = window.setTimeout(() => {
storageTimers[slot] = null;
refresh();
}, delay);
};
if (storageTimers.soon === null) schedule('soon', 0);
if (storageTimers.settled === null) schedule('settled', 50);
// Новое notification получает собственное trailing окно; ранние passes
// не перезапускаются. Максимум три timers, после тишины повторов нет.
if (storageTimers.trailing !== null) window.clearTimeout(storageTimers.trailing);
schedule('trailing', 250);
}
function choose(theme) { function choose(theme) {
if (theme !== 'light' && theme !== 'dark') return; if (theme !== 'light' && theme !== 'dark') return;
const from = shown; const from = shown;
@@ -66,7 +84,7 @@ $themeSurface = isset($themeSurface) && in_array($themeSurface, ['public', 'priv
const button = event.target instanceof Element ? event.target.closest('[data-theme-choice]') : null; const button = event.target instanceof Element ? event.target.closest('[data-theme-choice]') : null;
if (button && !button.disabled) choose(button.dataset.themeChoice); if (button && !button.disabled) choose(button.dataset.themeChoice);
}); });
window.addEventListener('storage', event => { if (event.key === key || event.key === null) refresh(); }); window.addEventListener('storage', event => { if (event.key === key || event.key === null) refreshAfterStorage(); });
window.addEventListener('pageshow', refresh); window.addEventListener('pageshow', refresh);
document.addEventListener('DOMContentLoaded', refresh); document.addEventListener('DOMContentLoaded', refresh);
document.addEventListener('pjax:end', refresh); document.addEventListener('pjax:end', refresh);