fix(footer): Close button now actually fires — wrong testid + bad fallback
Two bugs combined to make the footer Close a no-op: 1. The helper page_link's anchor carries ``data-testid="stPageLink-NavLink"`` — the bare ``stPageLink`` testid is on the OUTER WRAPPER div, not the anchor. The old selector ``a[data-testid="stPageLink"]`` matched nothing, so ``helper`` was always ``null``. 2. The fallback ``window.location.href = './close'`` ran inside the component iframe, so it only navigated the (invisible) srcdoc iframe. The main app stayed put. End result: click → nothing visible → shutdown_app never runs → farewell-script's ``window.close()`` attempt never happens → user sees the Close button as broken. Fixes: - Selector → ``a[data-testid="stPageLink-NavLink"][href*="close"]``. ``href*="close"`` covers both root (/close) and base-path (/myapp/close) deployments. - Fallback → resolve the parent window via ``doc.defaultView`` (the parent doc's window) with a ``window.top`` fallback, so the hard-nav navigates the whole app instead of just the iframe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -815,17 +815,29 @@ a[data-testid="stPageLink"][href$="/close/"] {
|
|||||||
// reload, no websocket churn. Fall back to a hard nav if the
|
// reload, no websocket churn. Fall back to a hard nav if the
|
||||||
// helper link hasn't rendered yet (first paint race) so the
|
// helper link hasn't rendered yet (first paint race) so the
|
||||||
// button is never a no-op.
|
// button is never a no-op.
|
||||||
|
//
|
||||||
|
// The page_link's anchor uses ``data-testid="stPageLink-NavLink"``
|
||||||
|
// (the outer wrapper div carries the bare ``stPageLink`` testid;
|
||||||
|
// dispatching click on the wrapper doesn't fire Streamlit's
|
||||||
|
// React onClick handler). ``href*="close"`` covers both root
|
||||||
|
// (/close) and base-path (e.g. /myapp/close) deployments.
|
||||||
closeBtn.addEventListener('click', function (e) {{
|
closeBtn.addEventListener('click', function (e) {{
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var helper = doc.querySelector(
|
var helper = doc.querySelector(
|
||||||
'a[data-testid="stPageLink"][href$="/close"], ' +
|
'a[data-testid="stPageLink-NavLink"][href*="close"]'
|
||||||
'a[data-testid="stPageLink"][href$="/close/"]'
|
|
||||||
);
|
);
|
||||||
if (helper) {{
|
if (helper) {{
|
||||||
helper.click();
|
helper.click();
|
||||||
}} else {{
|
return;
|
||||||
window.location.href = './close';
|
|
||||||
}}
|
}}
|
||||||
|
// Hard-nav fallback. ``window`` inside this script is the
|
||||||
|
// component iframe's window — changing ITS location only
|
||||||
|
// navigates the iframe (which lives in srcdoc and is
|
||||||
|
// invisible). Use the parent doc's location so the whole
|
||||||
|
// app navigates.
|
||||||
|
var topWin = (doc.defaultView) || window.parent || window.top || window;
|
||||||
|
try {{ topWin.location.href = './close'; }}
|
||||||
|
catch (err) {{ window.top.location.href = './close'; }}
|
||||||
}});
|
}});
|
||||||
|
|
||||||
div.appendChild(helpBtn);
|
div.appendChild(helpBtn);
|
||||||
|
|||||||
Reference in New Issue
Block a user