Fix context menu positioning and remove unnecessary width

This commit is contained in:
kodi
2026-03-28 08:12:29 +01:00
parent 9778dc6c33
commit 54e56ab0d8
9 changed files with 299 additions and 34 deletions
+42 -9
View File
@@ -436,7 +436,6 @@ function contextMenuElements() {
return {
menu: document.getElementById("context-menu"),
scope: document.getElementById("context-menu-scope"),
target: document.getElementById("context-menu-target"),
openButton: document.getElementById("context-menu-open-btn"),
editButton: document.getElementById("context-menu-edit-btn"),
downloadButton: document.getElementById("context-menu-download-btn"),
@@ -774,7 +773,8 @@ function closeContextMenu() {
}
elements.menu.classList.add("hidden");
elements.scope.textContent = "";
elements.target.textContent = "";
elements.menu.style.left = "";
elements.menu.style.top = "";
}
function openContextMenu(pane, entry, event) {
@@ -800,7 +800,6 @@ function openContextMenu(pane, entry, event) {
const editableSingle = items.length === 1 && !remoteSelection && isEditableSelection(items[0]);
const downloadableSelection = items.length === 1 && items[0].kind === "file";
elements.scope.textContent = isMulti ? "Multi-selection" : "Single item";
elements.target.textContent = isMulti ? `${items.length} selected items` : entry.name;
elements.openButton.classList.toggle("hidden", isMulti);
elements.openButton.disabled = !openableSingle;
elements.editButton.classList.toggle("hidden", isMulti || items.length !== 1 || items[0].kind !== "file" || remoteSelection);
@@ -819,13 +818,47 @@ function openContextMenu(pane, entry, event) {
elements.propertiesButton.classList.remove("hidden");
elements.propertiesButton.disabled = items.length === 0;
const menuWidth = 220;
const menuHeight = 120;
const x = Math.min(event.clientX, window.innerWidth - menuWidth - 12);
const y = Math.min(event.clientY, window.innerHeight - menuHeight - 12);
elements.menu.style.left = `${Math.max(8, x)}px`;
elements.menu.style.top = `${Math.max(8, y)}px`;
elements.menu.classList.remove("hidden");
positionContextMenu(elements.menu, event.currentTarget, event);
}
function positionContextMenu(menu, rowElement, event) {
if (!menu) {
return;
}
const paneElement = rowElement instanceof Element ? rowElement.closest(".pane") : null;
const paneRect = paneElement ? paneElement.getBoundingClientRect() : null;
const rowRect = rowElement instanceof Element ? rowElement.getBoundingClientRect() : null;
const menuRect = menu.getBoundingClientRect();
const viewportPadding = 8;
const panePadding = 8;
const minLeft = paneRect ? Math.max(viewportPadding, paneRect.left + panePadding) : viewportPadding;
const maxLeft = paneRect
? Math.max(minLeft, Math.min(window.innerWidth - viewportPadding - menuRect.width, paneRect.right - panePadding - menuRect.width))
: Math.max(minLeft, window.innerWidth - viewportPadding - menuRect.width);
const preferredLeft = rowRect ? rowRect.left + 12 : event.clientX;
const left = Math.max(minLeft, Math.min(maxLeft, preferredLeft));
const paneTop = paneRect ? paneRect.top + panePadding : viewportPadding;
const paneBottom = paneRect ? paneRect.bottom - panePadding : window.innerHeight - viewportPadding;
const rowTop = rowRect ? rowRect.top : event.clientY;
const rowBottom = rowRect ? rowRect.bottom : event.clientY;
const spaceBelow = paneBottom - rowBottom;
const spaceAbove = rowTop - paneTop;
let top;
if (spaceBelow >= menuRect.height || spaceBelow >= spaceAbove) {
top = rowBottom;
} else if (spaceAbove >= menuRect.height) {
top = rowTop - menuRect.height;
} else {
top = Math.max(paneTop, Math.min(paneBottom - menuRect.height, rowBottom));
}
top = Math.max(paneTop, Math.min(top, paneBottom - menuRect.height));
menu.style.left = `${left}px`;
menu.style.top = `${top}px`;
}
function applyContextMenuSelection() {