Commit f8d2cba1 authored by Romain Casati's avatar Romain Casati
Browse files

Fix PythonTutor's iframe overflow.

parent 42ab1121
......@@ -26,6 +26,36 @@ with open(pkg_resources.resource_filename('tutor', 'iframe.html')) as f:
iframe_template = f.read()
_iframe_count = -1
def _new_iframe_id():
global _iframe_count
_iframe_count += 1
return f"basthon-pythontutor-iframe-{_iframe_count}"
# to dynamically set the iframe height we nee this communication
# system between iframe and parent
def _iframe_resize(event, *args):
data = event.data
if data is None:
return
type = data.type
if type != 'pytutor-iframe-resize':
return
target = data.target
height = data.height
if target is None or height is None:
return
js.document.getElementById(target).style.height = f"{int(height) + 20}px"
js.window.addEventListener('message', _iframe_resize)
def tutor(**kwargs):
"""
Tutor the current executed script with PythonTutor.
......@@ -66,12 +96,17 @@ def tutor(**kwargs):
# generate PythonTutor trace
trace = json.dumps(generate_trace(code, **kwargs))
# get new iframe id
id = _new_iframe_id()
# building pytutor visualizer
iframe = iframe_template.format(
json_trace=trace,
extern_tutor_url=js.Basthon.basthonModulesRoot() + '/extern')
iframe = f'<iframe style="width: 100%; height: 400px; max-height: 100%;" frameborder="0" src="data:text/html;charset=utf-8,{quote(iframe)}"></iframe>'
extern_tutor_url=js.Basthon.basthonModulesRoot() + '/extern',
iframe_id=id)
iframe = f'<div style="width: 100%; height: 100%; overflow: auto;"><iframe id="{id}" style="width: 100%; height: 400px;" frameborder="0" src="data:text/html;charset=utf-8,{quote(iframe)}"></iframe></div>'
# sending node to Basthon for rendering
kernel.display_event({"display_type": "html",
"content": iframe})
"content": iframe,
"iframe-id": id})
......@@ -4,20 +4,35 @@
<link rel="stylesheet" href="{extern_tutor_url}/pytutor-main.min.css"/>
<script src="{extern_tutor_url}/pytutor-main.min.js"></script>
<script>
let sent_height;
$(document).ready(function() {{
var t = {json_trace};
var v = new ExecutionVisualizer(
// managing iframe resize
const send = () => {{
const new_height = document.body.offsetHeight;
if (sent_height === new_height) return;
sent_height = new_height;
window.parent.postMessage({{
type: "pytutor-iframe-resize",
target: "{iframe_id}",
height: sent_height,
}}, '*');
}};
const o = new ResizeObserver(send);
o.observe(document.body);
const t = {json_trace};
function redraw() {{ if (window.v) window.v.redrawConnectors(); }}
window.v = new ExecutionVisualizer(
'main', t,
{{embeddedMode: false,
heightChangeCallback: redraw}}
);
function redraw() {{ if (v) v.redrawConnectors(); }}
$(window).resize(redraw);
redraw();
}});
</script>
</head>
<body>
<body style="overflow-y: hidden;">
<div id="main"></div>
</body>
</html>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment