Compare commits

...
Author SHA1 Message Date
l0ng-ai d2d372e484 fix(editor): keep hover documentation inside its popup near the window edge
When little space is left above or below, CodeMirror caps the hover
tooltip's height, but the documentation section kept its own 380px
maximum and ran past the popup's border. The tooltip is now a flex
column whose sections shrink and scroll within it.
2026-11-12 19:12:36 +08:00
2 changed files with 40 additions and 1 deletions

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
import { expect, test } from "@playwright/test";
/** Near the window edge CodeMirror caps a hover tooltip's height (#2910). */
test("hover sections scroll inside a height-capped tooltip", async ({ page }) => {
await page.goto("/");
const r = await page.evaluate(async () => {
const viewMod = await import("/node_modules/.vite/deps/@codemirror_view.js" as string);
const stateMod = await import("/node_modules/.vite/deps/@codemirror_state.js" as string);
const { lspTheme } = await import("/src/editor/lsp/theme.ts" as string);
const host = document.createElement("div");
host.style.cssText = "position:fixed;inset:0;z-index:99999;background:white";
document.body.append(host);
const view = new viewMod.EditorView({
state: stateMod.EditorState.create({ doc: "x", extensions: lspTheme }),
parent: host,
});
const tip = document.createElement("div");
tip.className = "cm-tooltip cm-tooltip-hover";
tip.style.cssText = "position:absolute;top:10px;left:10px;height:200px";
const sec = document.createElement("div");
sec.className = "cm-tooltip-section cm-lsp-hover";
sec.innerHTML = Array.from({ length: 40 }, (_, i) => `<p>line ${i}</p>`).join("");
tip.append(sec);
view.dom.append(tip);
const t = tip.getBoundingClientRect(),
s = sec.getBoundingClientRect();
return {
tip: Math.round(t.height),
secBottom: Math.round(s.bottom),
tipBottom: Math.round(t.bottom),
scrolls: sec.scrollHeight > sec.clientHeight,
};
});
expect(r.secBottom).toBeLessThanOrEqual(r.tipBottom);
expect(r.scrolls).toBe(true);
});
+4 -1
View File
@@ -192,7 +192,10 @@ export const lspTheme = EditorView.theme({
".cm-lsp-doc-signature": { marginTop: "0", color: "var(--fg-emphasis)" },
// --- hover / quick documentation / signature / hints ---------------------
".cm-tooltip.cm-tooltip-hover": { ...tooltipSurface },
// Near the window edge CodeMirror caps the tooltip's height to the space left: its sections then
// shrink and scroll inside the popup instead of running past its border.
".cm-tooltip.cm-tooltip-hover": { ...tooltipSurface, display: "flex", flexDirection: "column" },
".cm-tooltip-hover > .cm-tooltip-section": { minHeight: 0, flexShrink: 1 },
".cm-lsp-hover": { maxWidth: "580px", maxHeight: "380px", overflow: "auto", padding: "10px 14px" },
".cm-lsp-hover-diagnostics + .cm-lsp-markdown": {
borderTop: "1px solid var(--border-popup)",