fix(editor): File→Quit returns to the management app it was entered from

The quit hook only history.back()ed on a SAME-ORIGIN referrer, so the
primary closed-deploy entry — app.pcbjam.com deep-linking into
editor.pcbjam.com (cross-origin) — fell through to the editor's own
project view instead of returning to the app. Quit is Back-button
semantics (3a2255c): any non-empty referrer with in-tab history now
goes back; deep links / fresh tabs (no referrer) keep the project-page
fallback. Verified live against the closed stack: :3047 → editor →
quit lands back on :3047; a direct editor URL still falls back to the
editor's project overview.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Istvan Matejcsok 2026-07-14 14:28:49 +02:00
commit 985408ce9e
2 changed files with 11 additions and 15 deletions

View file

@ -73,8 +73,8 @@ test.describe('web app — File → Quit leaves the editor', () => {
test('quit on a deep-linked editor falls back to the project page', async ({ page }) => {
test.setTimeout(300000);
// Direct entry: no same-origin referrer, nothing meaningful to go back to —
// quit must land on the project page via the fallback URL.
// Direct entry (typed URL): no referrer, nothing meaningful to go back
// to — quit must land on the project page via the fallback URL.
await page.goto(`/${SCOPE}/projects/demo/demo.kicad_sch`);
await waitForToolReady(page, /demo — Schematic Editor/i);

View file

@ -314,18 +314,14 @@ function installQuitHook(
opts: { fallbackUrl: string; log: (m: string) => void },
): () => void {
const hook = () => {
// A same-origin referrer means we entered by an in-app hard navigation
// (ProjectView / NewFileDialog / tool-switch all location.assign), so
// going back lands wherever the user came from. Deep links and fresh tabs
// have no usable history — go to the fallback instead.
let sameOriginReferrer = false;
try {
sameOriginReferrer =
!!win.document.referrer &&
new URL(win.document.referrer).origin === win.location.origin;
} catch {
sameOriginReferrer = false;
}
// Any referrer means we entered by a real navigation — an in-app hard
// navigation (ProjectView / NewFileDialog / tool-switch all
// location.assign) OR the cross-origin management app (app.pcbjam.com →
// editor.pcbjam.com deep-links; the primary entry in the closed deploy).
// Quit behaves like the Back button: going back lands wherever the user
// came from. Deep links and fresh tabs have no referrer and no usable
// history — go to the fallback instead.
const hasReferrer = !!win.document.referrer;
// Defer the navigation out of the wasm callback: this fires from inside the
// frame's C++ destructor (via EM_ASM under Asyncify), and the teardown keeps
@ -333,7 +329,7 @@ function installQuitHook(
// aborted by that continuing teardown (only the same-document history.back()
// survives) — so hand it to a fresh task once the wasm stack has unwound.
setTimeout(() => {
if (sameOriginReferrer && win.history.length > 1) {
if (hasReferrer && win.history.length > 1) {
opts.log("[quit] editor closed — history.back()");
win.history.back();
} else {