Skip to content

Commit 44166ec

Browse files
committed
working further on polishing stable html rendering
1 parent 9a62934 commit 44166ec

File tree

3 files changed

+28
-209
lines changed

3 files changed

+28
-209
lines changed

src/packages/frontend/jupyter/output-messages/cached-iframe.tsx

Lines changed: 0 additions & 178 deletions
This file was deleted.

src/packages/frontend/jupyter/output-messages/iframe.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import ReactDOM from "react-dom";
1313
import useIsMountedRef from "@cocalc/frontend/app-framework/is-mounted-hook";
1414
import useCounter from "@cocalc/frontend/app-framework/counter-hook";
1515
import { get_blob_url } from "../server-urls";
16-
import CachedIFrame from "./cached-iframe";
1716
import { useIFrameContext } from "@cocalc/frontend/jupyter/cell-list";
1817
import HTML from "./mime-types/html";
1918

@@ -24,7 +23,7 @@ const MAX_WAIT = 5000;
2423
const BACKOFF = 1.3;
2524

2625
const HEIGHT = "70vh";
27-
const WIDTH = "max(800px,70vw)";
26+
const WIDTH = "100vw";
2827

2928
interface Props {
3029
sha1: string;
@@ -53,8 +52,6 @@ export default function IFrame(props: Props) {
5352
value={`<iframe src="${src}" style="border:0;height:${HEIGHT};width:${WIDTH}"/>`}
5453
/>
5554
);
56-
// @ts-ignore
57-
return <CachedIFrame {...props} />;
5855
}
5956
}
6057

src/packages/frontend/jupyter/output-messages/stable-unsafe-html.tsx

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,18 @@ import { useIFrameContext } from "@cocalc/frontend/jupyter/cell-list";
3131
import { sha1 } from "@cocalc/util/misc";
3232
import TTL from "@isaacs/ttlcache";
3333

34+
// AFter this many seconds, an element that hasn't been in the react dom and whose
35+
// parent hasn't been scrolled, will get un-rendered.
3436
const IDLE_TIMEOUT_S = 10 * 60; // 10 minutes
37+
// If there are more than this many elements, old ones are un-rendered.
3538
const MAX_ELEMENTS = 500; // max items
39+
// Rough assumption about size of scrollbar.
40+
const SCROLL_WIDTH = 30;
41+
// we have to put the html on top of the notebook to be visible. This is the z-index we use.
42+
const Z_INDEX = 1;
43+
// no matter what when the html is in the REACT dom, it will have its position updated this frequently.
44+
// it also gets updated on scroll of the cell list.
45+
const POSITION_WHEN_MOUNTED_INTERVAL_MS = 500;
3646

3747
const cache = new TTL<string, any>({
3848
ttl: IDLE_TIMEOUT_S * 1000,
@@ -43,11 +53,6 @@ const cache = new TTL<string, any>({
4353
elt.remove();
4454
},
4555
});
46-
// const cache: { [globalKey: string]: any } = {};
47-
48-
const Z_INDEX = 1;
49-
50-
const SCROLL_COUNT = 25;
5156

5257
// make it really standout:
5358
// const PADDING = 5;
@@ -110,9 +115,9 @@ export default function StableUnsafeHtml({
110115
divRef.current.style.height = `${
111116
eltRect.bottom - eltRect.top + 2 * PADDING
112117
}px`;
113-
divRef.current.style.width = `${
114-
eltRect.right - eltRect.left + 2 * PADDING
115-
}px`;
118+
// divRef.current.style.width = `${
119+
// eltRect.right - eltRect.left + 2 * PADDING
120+
// }px`;
116121

117122
// clip our immortal html so it isn't visible outside the parent
118123
const parent = $(iframeContext.cellListDivRef?.current)[0];
@@ -123,26 +128,29 @@ export default function StableUnsafeHtml({
123128
// leave 30px on right so to not block scrollbar
124129
const right = Math.min(
125130
eltRect.width,
126-
parentRect.right - 30 - eltRect.left,
131+
parentRect.right - SCROLL_WIDTH - eltRect.left,
127132
);
128133
const bottom = Math.min(eltRect.height, parentRect.bottom - eltRect.top);
129134
const left = Math.max(0, parentRect.left - eltRect.left);
130135

131136
// Apply clip-path to elt to make it visible only inside of parentRect:
132137
elt.style.clipPath = `polygon(${left}px ${top}px, ${right}px ${top}px, ${right}px ${bottom}px, ${left}px ${bottom}px)`;
133138

139+
// Set widht, so it possible to scroll horizontally and see whatever widget is in the output.
140+
const w = $(divRef.current).width();
141+
if (w) {
142+
elt.style.width = `${w}px`;
143+
}
144+
134145
// if its an iframe resize it
135146
if (html.toLowerCase().startsWith("<iframe")) {
136147
const iframe = jElt.find("iframe");
137148
if (iframe.length > 0) {
138149
var iframeBody = iframe.contents().find("body");
139150
if (iframeBody.length > 0) {
140151
// Get dimensions of the iframe's body
141-
//const width = iframeBody.outerWidth();
142152
const height = iframeBody.outerHeight();
143-
//iframe[0].style.width = `${width}px`;
144153
iframe[0].style.height = `${height}px`;
145-
iframeBody[0].style["overflow-y"] = "hidden";
146154
}
147155
}
148156
}
@@ -152,7 +160,7 @@ export default function StableUnsafeHtml({
152160
const getElt = () => {
153161
if (!cache.has(globalKey)) {
154162
const elt = $(
155-
`<div id="${globalKey}" style="border:0;position:absolute;overflow-y:hidden;z-index:${zIndex}"/>${html}</div>`,
163+
`<div id="${globalKey}" style="border:0;position:absolute;overflow:auto;z-index:${zIndex}"/>${html}</div>`,
156164
);
157165
// @ts-ignore
158166
elt.process_smc_links();
@@ -191,27 +199,19 @@ export default function StableUnsafeHtml({
191199
useEffect(() => {
192200
// TOOD: can we get rid of interval by using a resize observer on
193201
// this iframeContext.cellListDivRef?
194-
intervalRef.current = setInterval(position, 500);
202+
intervalRef.current = setInterval(
203+
position,
204+
POSITION_WHEN_MOUNTED_INTERVAL_MS,
205+
);
195206
if (iframeContext.iframeOnScrolls != null) {
196-
let count = 0;
197207
iframeContext.iframeOnScrolls[globalKey] = async () => {
198-
// We run position a lot whenever there is a scroll
199-
// in order to make it so the iframe doesn't appear
200-
// to just get "dragged along" nearly as much, as
201-
// onScroll is throttled.
202-
count = SCROLL_COUNT;
203-
while (count > 0) {
204-
position();
205-
await new Promise(requestAnimationFrame);
206-
count -= 1;
207-
}
208-
// throw in an update when we're done.
208+
position();
209+
await new Promise(requestAnimationFrame);
209210
position();
210211
};
211212
}
212213
position();
213214
setTimeout(position, 0);
214-
setTimeout(position, 5);
215215

216216
return () => {
217217
delete iframeContext.iframeOnScrolls?.[globalKey];

0 commit comments

Comments
 (0)