@@ -13,10 +13,13 @@ import { decode } from "he";
13
13
//import { getLogger } from "@cocalc/backend/logger";
14
14
//const logger = getLogger("jupyter:blobs:iframe");
15
15
16
+ // see https://github.com/sagemathinc/cocalc/issues/4322
17
+ const MAX_HTML_SIZE = 10 ** 6 ;
18
+
16
19
// We use iframes to render html in a number of cases:
17
20
// - if it starts with iframe
18
21
// - if it has a whole page doctype
19
- // - if it has a <script> tag anywhere without a type -- since those are ignored by safe HTML
22
+ // - if it has a <script> tag anywhere -- since those are ignored by safe HTML
20
23
// rendering; using an iframe is the only way. This e.g., makes mpld3 work uses -- <script>! https://github.com/sagemathinc/cocalc/issues/1934
21
24
// and altair -- https://github.com/sagemathinc/cocalc/issues/4468 -- uses <script type="text/javascript"/>
22
25
// - do NOT just render all html in an iframe, e.g., this would break bokeh, since one output creates the target elt,
@@ -26,13 +29,28 @@ export function is_likely_iframe(content: string): boolean {
26
29
return false ;
27
30
}
28
31
content = content . toLowerCase ( ) ;
32
+ if (
33
+ content . includes ( "https://bokeh.org" ) &&
34
+ content . includes ( "bk-notebook-logo" )
35
+ ) {
36
+ // Do NOT use an iframe for bokeh no matter what, since this won't work properly.
37
+ // Hopefully the above heuristic is sufficiently robust to detect but not overdetect.
38
+ return false ;
39
+ }
40
+ if ( content . length >= MAX_HTML_SIZE ) {
41
+ // it'll just break anyways if we don't use an iframe -- if we do, there is hope.
42
+ return true ;
43
+ }
29
44
return (
30
45
content . includes ( "bk-notebook-logo" ) ||
31
46
content . startsWith ( "<iframe" ) ||
32
47
content . includes ( "<!doctype html>" ) ||
33
48
( content . includes ( "<html>" ) && content . includes ( "<head>" ) ) ||
34
- content . includes ( "<script>" ) ||
35
- content . includes ( '<script type="text/javascript">' )
49
+ // this gets really serious -- we sanitize out script tags in non-iframe html,
50
+ // and a LOT of interesting jupyter outputs are self contained html + script tags... so
51
+ // by rendering them all in iframes (1) they suddenly all work, which is great, and
52
+ // (2) if they are large (which is common) they work even better, by far!
53
+ content . includes ( "<script" )
36
54
) ;
37
55
}
38
56
0 commit comments