// Debug probe: measure the live layout when the inline row is open. // Reports bounding rects + the actual hit-test target at the #inline-ok button. import { createServer } from "node:http"; import { readFile } from "node:fs/promises"; import { extname, join, normalize, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { chromium } from "playwright"; const ROOT = resolve(fileURLToPath(new URL("..", import.meta.url))); const PORT = 8933; const MIME = { ".html": "text/html; charset=utf-8", ".js": "text/javascript; charset=utf-8", ".mjs": "text/javascript; charset=utf-8", ".cjs": "text/javascript; charset=utf-8", ".css": "text/css; charset=utf-8", ".txt": "text/plain; charset=utf-8", ".json": "application/json", ".wasm": "application/wasm", }; const server = createServer(async (req, res) => { let path = decodeURIComponent(new URL(req.url ?? "/", `http://localhost:${PORT}`).pathname); if (path === "/") path = "/demo/harness.html"; try { const data = await readFile(join(ROOT, normalize(path))); res.writeHead(200, { "content-type": MIME[extname(path)] ?? "application/octet-stream", "cross-origin-opener-policy": "same-origin", "cross-origin-embedder-policy": "require-corp", "service-worker-allowed": "/", }); res.end(data); } catch { res.writeHead(404).end("nope"); } }); await new Promise((r) => server.listen(PORT, r)); const browser = await chromium.launch(); const page = await browser.newPage(); page.on("console", (m) => console.log(`[console.${m.type()}]`, m.text())); page.on("pageerror", (e) => console.log("[pageerror]", e.message)); await page.goto(`http://localhost:${PORT}/demo/harness.html`); await page.waitForSelector('#tree [data-path="/app"]', { timeout: 20_000 }); // Open the inline row the way the tests do, then measure. await page.locator('#tree [data-path="/app"]').click({ button: "right" }); await page.waitForSelector("#context-menu", { state: "visible" }); await page.locator("#ctx-new-file").click(); await page.waitForSelector("#inline-row", { state: "visible" }); const report = await page.evaluate(() => { const rect = (id) => { const e = document.getElementById(id); if (!e) return null; const r = e.getBoundingClientRect(); return { id, x: r.x, y: r.y, w: r.width, h: r.height, right: r.right, bottom: r.bottom }; }; const ids = ["app", "sidebar", "inline-row", "inline-label", "inline-input", "inline-ok", "inline-cancel", "main", "editor", "editor-body", "content", "hl-wrap", "md-editor", "gutter", "tabs", "output", "status"]; const rects = ids.map(rect); const ok = document.getElementById("inline-ok"); const r = ok.getBoundingClientRect(); const cx = r.x + r.width / 2; const cy = r.y + r.height / 2; const stack = document.elementsFromPoint(cx, cy).slice(0, 6).map((e) => `${e.tagName.toLowerCase()}${e.id ? "#" + e.id : ""}`); const cs = (id, props) => { const e = document.getElementById(id); if (!e) return null; const s = getComputedStyle(e); return Object.fromEntries(props.map((p) => [p, s[p]])); }; return { rects, clickPoint: { cx, cy }, hitStack: stack, inlineOkComputed: cs("inline-ok", ["position", "zIndex", "gridRow", "gridColumn", "display"]), inlineLabelComputed: cs("inline-label", ["flexShrink", "flexGrow", "flexBasis", "minWidth", "width"]), inlineInputComputed: cs("inline-input", ["flexShrink", "flexGrow", "flexBasis", "minWidth", "width"]), editorComputed: cs("editor", ["position", "zIndex", "gridRow", "gridColumn", "transform", "margin"]), mainComputed: cs("main", ["gridArea", "position", "zIndex", "transform", "margin"]), sidebarComputed: cs("sidebar", ["gridArea", "position", "zIndex", "width", "transform"]), appColumns: getComputedStyle(document.getElementById("app")).gridTemplateColumns, appAreas: getComputedStyle(document.getElementById("app")).gridTemplateAreas, }; }); console.log(JSON.stringify(report, null, 2)); await browser.close(); server.close();