From 8c3b585fec62d133687430530ae6c3facbb6f462 Mon Sep 17 00:00:00 2001 From: abose Date: Sun, 24 May 2026 11:50:53 +0530 Subject: [PATCH] fix(mdviewer): slash menu positioned at right edge instead of cursor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The horizontal-overflow clamp in show() wrote a viewport coordinate to menu.style.left, but .slash-menu is position:absolute inside a position:fixed anchor — left is anchor-relative, not viewport-relative. The menu jumped to viewport x ≈ (cursor.x + 895) and stayed there because show() never reset menu.style.left between opens, letting the stale value re-trigger the clamp on every subsequent /. - Reset menu.style.left at the start of show() - Convert the clamp from viewport coords to anchor-relative --- src-mdviewer/src/components/slash-menu.js | 11 +++++++++-- src-node/package-lock.json | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src-mdviewer/src/components/slash-menu.js b/src-mdviewer/src/components/slash-menu.js index 1db369b1cd..f69fbe5511 100644 --- a/src-mdviewer/src/components/slash-menu.js +++ b/src-mdviewer/src/components/slash-menu.js @@ -231,6 +231,10 @@ function show() { anchor.style.left = rect.left + "px"; anchor.style.top = rect.bottom + 4 + "px"; + // Reset menu offset — values are anchor-relative, so stale ones from a + // previous open would shift the menu away from the new cursor position. + menu.style.left = ""; + anchor.classList.add("visible"); menu.scrollTop = 0; visible = true; @@ -251,10 +255,13 @@ function show() { menu.style.bottom = "0"; } - // Clamp horizontal + // Clamp horizontal. menu.style.left is an offset from the anchor + // (the anchor is position:fixed and acts as the containing block), + // so a viewport coordinate must be converted before assigning. const menuRect = menu.getBoundingClientRect(); if (menuRect.right > window.innerWidth - 8) { - menu.style.left = Math.max(8, window.innerWidth - menuRect.width - 8) + "px"; + const clampedViewportLeft = Math.max(8, window.innerWidth - menuRect.width - 8); + menu.style.left = (clampedViewportLeft - rect.left) + "px"; } }); } diff --git a/src-node/package-lock.json b/src-node/package-lock.json index 051245b909..918476129a 100644 --- a/src-node/package-lock.json +++ b/src-node/package-lock.json @@ -1,12 +1,12 @@ { "name": "@phcode/node-core", - "version": "5.1.18-0", + "version": "5.1.20-0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@phcode/node-core", - "version": "5.1.18-0", + "version": "5.1.20-0", "hasInstallScript": true, "license": "GNU-AGPL3.0", "dependencies": {