Trigger iframe-resizer.size() after Gradio mounts so HF Spaces measures full app height
Browse files- demo/app.py +30 -0
demo/app.py
CHANGED
|
@@ -2856,6 +2856,7 @@ theme = gr.themes.Base(
|
|
| 2856 |
# behavior reliable across versions.
|
| 2857 |
_CHATBOT_AUTOSCROLL_JS = """
|
| 2858 |
() => {
|
|
|
|
| 2859 |
const tryAttach = () => {
|
| 2860 |
const containers = document.querySelectorAll('.er-chat .wrap, .er-chat .bubble-wrap, .er-chat > div, .er-chat');
|
| 2861 |
let target = null;
|
|
@@ -2875,6 +2876,35 @@ _CHATBOT_AUTOSCROLL_JS = """
|
|
| 2875 |
scroll();
|
| 2876 |
};
|
| 2877 |
tryAttach();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2878 |
}
|
| 2879 |
"""
|
| 2880 |
|
|
|
|
| 2856 |
# behavior reliable across versions.
|
| 2857 |
_CHATBOT_AUTOSCROLL_JS = """
|
| 2858 |
() => {
|
| 2859 |
+
// Chatbot auto-scroll on streaming updates.
|
| 2860 |
const tryAttach = () => {
|
| 2861 |
const containers = document.querySelectorAll('.er-chat .wrap, .er-chat .bubble-wrap, .er-chat > div, .er-chat');
|
| 2862 |
let target = null;
|
|
|
|
| 2876 |
scroll();
|
| 2877 |
};
|
| 2878 |
tryAttach();
|
| 2879 |
+
|
| 2880 |
+
// HF Spaces iframe-resizer fix.
|
| 2881 |
+
// HF embeds Gradio in an iframe sized by iframe-resizer in `taggedElement`
|
| 2882 |
+
// mode. iframe-resizer scans the DOM at page-load and gives up when it
|
| 2883 |
+
// finds nothing tagged with `data-iframe-height` — but Gradio is a Svelte
|
| 2884 |
+
// SPA, so our tagged element does not exist in the DOM yet at that moment.
|
| 2885 |
+
// The result is the iframe staying at its tiny default height and clipping
|
| 2886 |
+
// the top of our app (topbar / hero invisible).
|
| 2887 |
+
//
|
| 2888 |
+
// Fix: after each Gradio re-render, ask iframe-resizer to re-measure via
|
| 2889 |
+
// its parentIFrame.size() API, and as a fallback dispatch a window resize
|
| 2890 |
+
// event (which iframe-resizer also listens to).
|
| 2891 |
+
const triggerIframeResize = () => {
|
| 2892 |
+
try {
|
| 2893 |
+
if (window.parentIFrame && typeof window.parentIFrame.size === 'function') {
|
| 2894 |
+
window.parentIFrame.size();
|
| 2895 |
+
}
|
| 2896 |
+
window.dispatchEvent(new Event('resize'));
|
| 2897 |
+
} catch (e) { /* noop — only relevant when embedded in HF Spaces */ }
|
| 2898 |
+
};
|
| 2899 |
+
// Trigger on initial mount, then watch for any DOM changes (e.g. new chat
|
| 2900 |
+
// messages, accordion expand) and re-trigger so the iframe grows with us.
|
| 2901 |
+
setTimeout(triggerIframeResize, 100);
|
| 2902 |
+
setTimeout(triggerIframeResize, 600);
|
| 2903 |
+
setTimeout(triggerIframeResize, 1500);
|
| 2904 |
+
const resizeObs = new MutationObserver(() => {
|
| 2905 |
+
requestAnimationFrame(triggerIframeResize);
|
| 2906 |
+
});
|
| 2907 |
+
resizeObs.observe(document.body, { childList: true, subtree: true });
|
| 2908 |
}
|
| 2909 |
"""
|
| 2910 |
|