2026-07-06 21:12:26 -03:00
|
|
|
/*
|
2026-07-18 22:43:41 -03:00
|
|
|
* OrganonTweaks -- keep the board's horizontal scroll position across refreshes AND full reloads.
|
2026-07-06 21:12:26 -03:00
|
|
|
*
|
2026-07-18 22:43:41 -03:00
|
|
|
* Two cases lose the horizontal scroll and snap the board back to the first column:
|
|
|
|
|
* 1. AJAX rebuild -- dropping a card / periodic polling replaces #board-container
|
|
|
|
|
* (BoardDragAndDrop.refresh), and the new element starts at scrollLeft 0.
|
|
|
|
|
* 2. Full page reload -- e.g. clicking the Done/Todo badge, which navigates and redirects back to
|
|
|
|
|
* the board; a fresh page starts at scrollLeft 0.
|
2026-07-06 21:12:26 -03:00
|
|
|
*
|
2026-07-18 22:43:41 -03:00
|
|
|
* We remember the last position and restore it: in-memory for the AJAX rebuild (observing the STABLE
|
|
|
|
|
* parent, since the container itself is replaced), and in sessionStorage (keyed per board) so it
|
|
|
|
|
* survives a full reload as well.
|
2026-07-06 21:12:26 -03:00
|
|
|
*/
|
|
|
|
|
(function () {
|
|
|
|
|
"use strict";
|
|
|
|
|
|
2026-07-18 22:43:41 -03:00
|
|
|
function boardKey() {
|
|
|
|
|
var m = location.href.match(/board\/(\d+)/) || location.href.match(/project_id=(\d+)/);
|
|
|
|
|
return "organon-board-scroll-" + (m ? m[1] : location.pathname);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function readStored() {
|
|
|
|
|
try {
|
|
|
|
|
var v = window.sessionStorage.getItem(boardKey());
|
|
|
|
|
return v ? parseInt(v, 10) : 0;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeStored(value) {
|
|
|
|
|
try {
|
|
|
|
|
window.sessionStorage.setItem(boardKey(), value);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
// sessionStorage unavailable (private mode / disabled) -- degrade to AJAX-only restore.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-06 21:12:26 -03:00
|
|
|
function init() {
|
|
|
|
|
var container = document.getElementById("board-container");
|
|
|
|
|
if (!container) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parent = container.parentNode;
|
2026-07-18 22:43:41 -03:00
|
|
|
var stored = readStored();
|
|
|
|
|
var lastScrollLeft = stored || container.scrollLeft;
|
2026-07-06 21:12:26 -03:00
|
|
|
var lastContainer = container;
|
|
|
|
|
|
2026-07-18 22:43:41 -03:00
|
|
|
// Restore across a full page reload (badge click, etc.), not only AJAX rebuilds.
|
|
|
|
|
if (stored && container.scrollLeft !== stored) {
|
|
|
|
|
container.scrollLeft = stored;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remember the position whenever the board is scrolled (capture: scroll does not bubble, and
|
|
|
|
|
// this survives the container being replaced).
|
2026-07-06 21:12:26 -03:00
|
|
|
document.addEventListener("scroll", function (e) {
|
|
|
|
|
var c = document.getElementById("board-container");
|
|
|
|
|
if (c && e.target === c) {
|
|
|
|
|
lastScrollLeft = c.scrollLeft;
|
2026-07-18 22:43:41 -03:00
|
|
|
writeStored(lastScrollLeft);
|
2026-07-06 21:12:26 -03:00
|
|
|
}
|
|
|
|
|
}, true);
|
|
|
|
|
|
2026-07-18 22:43:41 -03:00
|
|
|
// When the board is rebuilt, #board-container becomes a new element at scrollLeft 0; restore
|
|
|
|
|
// the remembered position before the browser paints it.
|
2026-07-06 21:12:26 -03:00
|
|
|
if (window.MutationObserver) {
|
|
|
|
|
new MutationObserver(function () {
|
|
|
|
|
var c = document.getElementById("board-container");
|
|
|
|
|
if (c && c !== lastContainer) {
|
|
|
|
|
lastContainer = c;
|
|
|
|
|
if (c.scrollLeft !== lastScrollLeft) {
|
|
|
|
|
c.scrollLeft = lastScrollLeft;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}).observe(parent, { childList: true });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (document.readyState === "loading") {
|
|
|
|
|
document.addEventListener("DOMContentLoaded", init);
|
|
|
|
|
} else {
|
|
|
|
|
init();
|
|
|
|
|
}
|
|
|
|
|
})();
|