Preserve card edit scroll position

This commit is contained in:
gitea_admin committed 2026-09-30 10:36:09 +02:00
1 parent ec6364b32b
commit 01fa2bc2b6
2 files changed
+57 -2

No files matched your search

+1 -1
View File
@@ -965,7 +965,7 @@ function render_auth_home_page(array $user, array $otcProducts = [], array $otcM
echo '</div>'; echo '</div>';
echo '</section>'; echo '</section>';
echo '<script src="/scripts/help-icon-overlays.js"></script>'; echo '<script src="/scripts/help-icon-overlays.js"></script>';
echo '<script src="/scripts/shared-editable-action-card.js?v=20260920-2"></script>'; echo '<script src="/scripts/shared-editable-action-card.js?v=20260930-1"></script>';
echo '<script src="/scripts/shared-mobile-detail.js?v=20260925-1"></script>'; echo '<script src="/scripts/shared-mobile-detail.js?v=20260925-1"></script>';
echo '<script src="/scripts/large-table-column-resize.js?v=' . filemtime(__DIR__ . '/../../../../public/scripts/large-table-column-resize.js') . '"></script>'; echo '<script src="/scripts/large-table-column-resize.js?v=' . filemtime(__DIR__ . '/../../../../public/scripts/large-table-column-resize.js') . '"></script>';
echo '<script>'; echo '<script>';
+56 -1
View File
@@ -2,9 +2,53 @@
'use strict'; 'use strict';
const cardSelector = '[data-shared-editable-action-card]'; const cardSelector = '[data-shared-editable-action-card]';
const scrollRestoreStates = new WeakMap();
const getCard = (element) => element.closest(cardSelector); const getCard = (element) => element.closest(cardSelector);
const getScrollContainer = (element) => {
let candidate = element?.parentElement || null;
while (candidate && candidate !== document.body) {
const style = window.getComputedStyle(candidate);
const scrollable = /(auto|scroll|overlay)/.test(style.overflowY);
if (scrollable && candidate.scrollHeight > candidate.clientHeight) {
return candidate;
}
candidate = candidate.parentElement;
}
return document.scrollingElement || document.documentElement;
};
const captureScrollPosition = (root, card) => {
const container = getScrollContainer(card);
scrollRestoreStates.set(root, {
card,
container,
top: container.scrollTop,
left: container.scrollLeft,
scheduled: false,
});
};
const restoreScrollPosition = (root) => {
const state = scrollRestoreStates.get(root);
if (!state || state.scheduled) {
return;
}
state.scheduled = true;
requestAnimationFrame(() => {
requestAnimationFrame(() => {
if (state.container?.isConnected) {
state.container.scrollTo({ top: state.top, left: state.left, behavior: 'auto' });
}
scrollRestoreStates.delete(root);
});
});
};
const getDirectDeleteElement = (card, selector) => Array.from(card?.children || []) const getDirectDeleteElement = (card, selector) => Array.from(card?.children || [])
.find((child) => child.matches(selector)) || null; .find((child) => child.matches(selector)) || null;
@@ -93,7 +137,9 @@
root.addEventListener('click', (event) => { root.addEventListener('click', (event) => {
const edit = event.target.closest('[data-shared-editable-card-edit]'); const edit = event.target.closest('[data-shared-editable-card-edit]');
if (edit && root.contains(edit)) { if (edit && root.contains(edit)) {
setEditMode(getCard(edit), true); const card = getCard(edit);
captureScrollPosition(root, card);
setEditMode(card, true);
return; return;
} }
@@ -102,6 +148,7 @@
const card = getCard(cancel); const card = getCard(cancel);
resetDeleteConfirmation(card); resetDeleteConfirmation(card);
setEditMode(card, false); setEditMode(card, false);
scrollRestoreStates.delete(root);
return; return;
} }
@@ -117,6 +164,14 @@
} }
}); });
const scrollObserver = new MutationObserver(() => {
const state = scrollRestoreStates.get(root);
if (state && !root.contains(state.card)) {
restoreScrollPosition(root);
}
});
scrollObserver.observe(root, { childList: true, subtree: true });
root.addEventListener('input', (event) => { root.addEventListener('input', (event) => {
const input = event.target.closest('[data-shared-editable-card-delete-input]'); const input = event.target.closest('[data-shared-editable-card-delete-input]');
if (input && root.contains(input)) { if (input && root.contains(input)) {