(x, y)
| 87 | |
| 88 | // Position menu within viewport |
| 89 | function placeMenu(x, y) { |
| 90 | const m = qMenu(); if (!m) return; |
| 91 | |
| 92 | // make visible to measure |
| 93 | m.hidden = false; |
| 94 | m.style.left = '0px'; |
| 95 | m.style.top = '0px'; |
| 96 | |
| 97 | // force a max-height via CSS fallback if styles didn't load yet |
| 98 | const pad = 8; |
| 99 | const vh = window.innerHeight, vw = window.innerWidth; |
| 100 | const mh = Math.min(vh - pad*2, 600); // JS fallback limit |
| 101 | m.style.maxHeight = mh + 'px'; |
| 102 | |
| 103 | // measure now that it's flow-visible |
| 104 | const r0 = m.getBoundingClientRect(); |
| 105 | let nx = x, ny = y; |
| 106 | |
| 107 | // If it would overflow right, shift left |
| 108 | if (nx + r0.width > vw - pad) nx = Math.max(pad, vw - r0.width - pad); |
| 109 | // If it would overflow bottom, try placing it above the cursor |
| 110 | if (ny + r0.height > vh - pad) { |
| 111 | const above = y - r0.height - 4; |
| 112 | ny = (above >= pad) ? above : Math.max(pad, vh - r0.height - pad); |
| 113 | } |
| 114 | |
| 115 | // Guard top/left minimums |
| 116 | nx = Math.max(pad, nx); |
| 117 | ny = Math.max(pad, ny); |
| 118 | |
| 119 | m.style.left = `${nx}px`; |
| 120 | m.style.top = `${ny}px`; |
| 121 | } |
| 122 | |
| 123 | export function hideFileContextMenu() { |
| 124 | const m = qMenu(); |
no test coverage detected