Fix leaderboard clipped/unscrollable inside HF Spaces iframe
Browse filesOn the huggingface.co/spaces wrapper page the app is embedded in an
iframe whose height is managed by iframe-resizer. Gradio's HF-embed
shell hardcodes it with autoResize:false, so the iframe height is
measured once at load -- before the async Dataframe/Plot components
expand -- and never updated. The frozen, too-short iframe clips the
tables/plots with no way to scroll to them (zooming only "worked"
because it forced a one-off re-measure).
Re-enable the library's continuous height syncing from the app via a
demo.load() js hook that calls parentIFrame.autoResize(true) once the
resizer handshake completes. This keeps the iframe height in step with
async renders, tab switches, and the Refresh button. No-op when not
embedded (window.parentIFrame is undefined locally / on the direct
*.hf.space URL).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@@ -386,6 +386,34 @@ with demo:
|
|
| 386 |
],
|
| 387 |
)
|
| 388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
|
| 390 |
|
| 391 |
scheduler = BackgroundScheduler()
|
|
|
|
| 386 |
],
|
| 387 |
)
|
| 388 |
|
| 389 |
+
# When embedded in the Hugging Face Spaces page, Gradio's shell hardcodes the
|
| 390 |
+
# iframe-resizer with `autoResize: false`, so the outer iframe's height is
|
| 391 |
+
# measured only once at load -- before the async-rendered Dataframe/Plot
|
| 392 |
+
# components expand -- and never updated again. The result is a frozen, too-short
|
| 393 |
+
# iframe that clips the leaderboard tables/plots and can't be scrolled to
|
| 394 |
+
# (zooming the page "fixes" it only because that forces a one-off re-measure).
|
| 395 |
+
# Re-enable the library's continuous height syncing so the iframe keeps up with
|
| 396 |
+
# async renders, tab switches, and the Refresh button. No-op outside an iframe.
|
| 397 |
+
demo.load(
|
| 398 |
+
None,
|
| 399 |
+
None,
|
| 400 |
+
None,
|
| 401 |
+
js="""
|
| 402 |
+
() => {
|
| 403 |
+
let tries = 0;
|
| 404 |
+
const iv = setInterval(() => {
|
| 405 |
+
if (window.parentIFrame && typeof window.parentIFrame.autoResize === "function") {
|
| 406 |
+
window.parentIFrame.autoResize(true);
|
| 407 |
+
window.parentIFrame.size();
|
| 408 |
+
clearInterval(iv);
|
| 409 |
+
} else if (++tries > 100) {
|
| 410 |
+
clearInterval(iv);
|
| 411 |
+
}
|
| 412 |
+
}, 100);
|
| 413 |
+
}
|
| 414 |
+
""",
|
| 415 |
+
)
|
| 416 |
+
|
| 417 |
|
| 418 |
|
| 419 |
scheduler = BackgroundScheduler()
|