Skip to content

Commit b4b4c5f

Browse files
author
Philip Guo
committed
start adding iframe support
1 parent 87f9014 commit b4b4c5f

6 files changed

Lines changed: 210 additions & 5 deletions

File tree

v3/iframe-embed-demo.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2+
<html xmlns="http://www.w3.org/1999/xhtml">
3+
4+
<head>
5+
<title>blah blah blah</title>
6+
</head>
7+
8+
<body>
9+
10+
</body>
11+
</html>

v3/iframe-embed.html

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2+
<html xmlns="http://www.w3.org/1999/xhtml">
3+
4+
<head>
5+
<title>Online Python Tutor - iframe embed page</title>
6+
7+
<!-- dependencies for pytutor.js -->
8+
<script type="text/javascript" src="js/d3.v2.min.js"></script>
9+
<script type="text/javascript" src="js/jquery-1.8.2.min.js"></script>
10+
<script type="text/javascript" src="js/jquery.ba-bbq.min.js"></script> <!-- for handling back button and URL hashes -->
11+
<script type="text/javascript" src="js/jquery.jsPlumb-1.3.10-all-min.js "></script> <!-- for rendering SVG connectors
12+
DO NOT UPGRADE ABOVE 1.3.10 OR ELSE BREAKAGE WILL OCCUR -->
13+
<script type="text/javascript" src="js/jquery-ui-1.8.24.custom.min.js"></script> <!-- for sliders and other UI elements -->
14+
<link type="text/css" href="css/ui-lightness/jquery-ui-1.8.24.custom.css" rel="stylesheet" />
15+
16+
17+
<!-- Python Tutor frontend code and styles -->
18+
<script type="text/javascript" src="js/pytutor.js"></script>
19+
<link rel="stylesheet" href="css/pytutor.css"/>
20+
21+
<script type="text/javascript" src="js/iframe-embed.js"></script>
22+
23+
</head>
24+
25+
<body>
26+
27+
<div id="vizDiv"></div>
28+
29+
</body>
30+
</html>

v3/js/iframe-embed.js

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
3+
Online Python Tutor
4+
https://github.com/pgbovine/OnlinePythonTutor/
5+
6+
Copyright (C) 2010-2012 Philip J. Guo (philip@pgbovine.net)
7+
8+
Permission is hereby granted, free of charge, to any person obtaining a
9+
copy of this software and associated documentation files (the
10+
"Software"), to deal in the Software without restriction, including
11+
without limitation the rights to use, copy, modify, merge, publish,
12+
distribute, sublicense, and/or sell copies of the Software, and to
13+
permit persons to whom the Software is furnished to do so, subject to
14+
the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included
17+
in all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26+
27+
*/
28+
29+
30+
// Pre-reqs: pytutor.js and jquery.ba-bbq.min.js should be imported BEFORE this file
31+
32+
33+
// backend scripts to execute (Python 2 and 3 variants, if available)
34+
//var python2_backend_script = 'web_exec_py2.py';
35+
//var python3_backend_script = 'web_exec_py3.py';
36+
37+
// uncomment below if you're running on Google App Engine using the built-in app.yaml
38+
var python2_backend_script = 'exec';
39+
var python3_backend_script = null;
40+
41+
42+
var myVisualizer = null; // singleton ExecutionVisualizer instance
43+
44+
45+
$(document).ready(function() {
46+
47+
var preseededCode = $.bbq.getState('code');
48+
var cumulativeState = $.bbq.getState('cumulative');
49+
var pyState = $.bbq.getState('py');
50+
51+
var preseededCurInstr = Number($.bbq.getState('curInstr'));
52+
if (!preseededCurInstr) {
53+
preseededCurInstr = 0;
54+
}
55+
56+
// TODO: add more options
57+
58+
59+
60+
var backend_script = null;
61+
if (pyState == '2') {
62+
backend_script = python2_backend_script;
63+
}
64+
else if (pyState == '3') {
65+
backend_script = python3_backend_script;
66+
}
67+
68+
if (!backend_script) {
69+
alert('Error: This server is not configured to run Python ' + $('#pythonVersionSelector').val());
70+
return;
71+
}
72+
73+
74+
$.get(backend_script,
75+
{user_script : preseededCode, cumulative_mode: cumulativeState},
76+
function(dataFromBackend) {
77+
var trace = dataFromBackend.trace;
78+
79+
// don't enter visualize mode if there are killer errors:
80+
if (!trace ||
81+
(trace.length == 0) ||
82+
(trace[trace.length - 1].event == 'uncaught_exception')) {
83+
84+
if (trace.length == 1) {
85+
alert(trace[0].exception_msg);
86+
}
87+
else if (trace[trace.length - 1].exception_msg) {
88+
alert(trace[trace.length - 1].exception_msg);
89+
}
90+
else {
91+
alert("Whoa, unknown error! Reload to try again, or report a bug to philip@pgbovine.net\n\n(Click the 'Generate URL' button to include a unique URL in your email bug report.)");
92+
}
93+
}
94+
else {
95+
var startingInstruction = 0;
96+
97+
// only do this at most ONCE, and then clear out preseededCurInstr
98+
if (preseededCurInstr && preseededCurInstr < trace.length) { // NOP anyways if preseededCurInstr is 0
99+
startingInstruction = preseededCurInstr;
100+
}
101+
102+
myVisualizer = new ExecutionVisualizer('vizDiv',
103+
dataFromBackend,
104+
{startingInstruction: preseededCurInstr,
105+
embeddedMode: true,
106+
editCodeBaseURL: 'http://pythontutor.com/visualize.html',
107+
});
108+
}
109+
},
110+
"json");
111+
112+
113+
// log a generic AJAX error handler
114+
$(document).ajaxError(function() {
115+
alert("Online Python Tutor server error (possibly due to memory/resource overload).");
116+
});
117+
118+
119+
// redraw connector arrows on window resize
120+
$(window).resize(function() {
121+
if (appMode == 'display') {
122+
myVisualizer.redrawConnectors();
123+
}
124+
});
125+
126+
});
127+

v3/js/opt-frontend.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ function setCodeMirrorVal(dat) {
6666

6767
$(document).ready(function() {
6868

69+
$("#embedLinkDiv").hide();
70+
6971
pyInputCodeMirror = CodeMirror(document.getElementById('codeInputPane'), {
7072
mode: 'python',
7173
lineNumbers: true,
@@ -87,11 +89,14 @@ $(document).ready(function() {
8789
if (appMode === undefined || appMode == 'edit') {
8890
$("#pyInputPane").show();
8991
$("#pyOutputPane").hide();
92+
$("#embedLinkDiv").hide();
9093
}
9194
else if (appMode == 'display') {
9295
$("#pyInputPane").hide();
9396
$("#pyOutputPane").show();
9497

98+
$("#embedLinkDiv").show();
99+
95100
$('#executeBtn').html("Visualize execution");
96101
$('#executeBtn').attr('disabled', false);
97102

@@ -132,6 +137,7 @@ $(document).ready(function() {
132137
$('#executeBtn').html("Please wait ... processing your code");
133138
$('#executeBtn').attr('disabled', true);
134139
$("#pyOutputPane").hide();
140+
$("#embedLinkDiv").hide();
135141

136142

137143
$.get(backend_script,
@@ -483,7 +489,7 @@ $(document).ready(function() {
483489

484490
// log a generic AJAX error handler
485491
$(document).ajaxError(function() {
486-
alert("Server error (possibly due to memory/resource overload).");
492+
alert("Server error (possibly due to memory/resource overload). Report a bug to philip@pgbovine.net\n\n(Click the 'Generate URL' button to include a unique URL in your email bug report.)");
487493

488494
$('#executeBtn').html("Visualize execution");
489495
$('#executeBtn').attr('disabled', false);
@@ -510,5 +516,19 @@ $(document).ready(function() {
510516
var urlStr = $.param.fragment(window.location.href, myArgs, 2 /* clobber all */);
511517
$('#urlOutput').val(urlStr);
512518
});
519+
520+
521+
$('#genEmbedBtn').bind('click', function() {
522+
assert(appMode == 'display');
523+
var myArgs = {code: pyInputCodeMirror.getValue(),
524+
cumulative: $('#cumulativeModeSelector').val(),
525+
py: $('#pythonVersionSelector').val(),
526+
curInstr: myVisualizer.curInstr,
527+
};
528+
529+
var embedUrlStr = $.param.fragment('http://pythontutor.com/iframe-embed.html', myArgs, 2 /* clobber all */);
530+
var iframeStr = '<iframe width="800" height="400" frameborder="0" src="' + embedUrlStr + '"> </iframe>';
531+
$('#embedCodeOutput').val(iframeStr);
532+
});
513533
});
514534

v3/pythontutor.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ def get(self):
4848
self.response.out.write(template.render())
4949

5050

51+
class IframeEmbedPage(webapp2.RequestHandler):
52+
def get(self):
53+
self.response.headers['Content-Type'] = 'text/html'
54+
template = JINJA_ENVIRONMENT.get_template('iframe-embed.html')
55+
self.response.out.write(template.render())
56+
57+
5158
class LessonPage(webapp2.RequestHandler):
5259

5360
def get(self):
@@ -76,6 +83,7 @@ def get(self):
7683

7784

7885
app = webapp2.WSGIApplication([('/', TutorPage),
86+
('/iframe-embed.html', IframeEmbedPage),
7987
('/lesson.html', LessonPage),
8088
('/exec', ExecScript)],
8189
debug=True)

v3/visualize.html

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,20 @@
170170
<button id="genUrlBtn" class="smallBtn" type="button">Generate URL</button> <input type="text" id="urlOutput" size="70"/>
171171
</p>
172172

173-
<p>To report a bug, click the 'Generate URL' button, paste the URL along
174-
with a brief error description in an email, and send the email to
175-
philip@pgbovine.net
173+
<p>To share this visualization, click the 'Generate URL' button above
174+
and share that URL. To report a bug, paste the URL along with a brief
175+
error description in an email addressed to philip@pgbovine.net</p>
176+
177+
<div id="embedLinkDiv">
178+
<p>
179+
<button id="genEmbedBtn" class="smallBtn" type="button">Generate embed code</button> <input type="text" id="embedCodeOutput" size="70"/>
176180
</p>
177181

182+
<p>To embed this visualization in your webpage, click the 'Generate
183+
embed code' button above and paste the resulting HTML code into your
184+
webpage. Adjust the height and width parameters as needed.</p>
185+
</div>
186+
178187
<a href="http://pythontutor.com/">Online Python Tutor</a> supports <a
179188
href="http://www.python.org/doc/2.7/">Python 2.7</a> and <a
180189
href="http://www.python.org/doc/3.2/">Python 3.2</a> with limited module
@@ -197,7 +206,7 @@
197206
href="https://github.com/pgbovine/OnlinePythonTutor/blob/master/v3/docs/user-FAQ.md">FAQ</a>
198207
or other <a
199208
href="https://github.com/pgbovine/OnlinePythonTutor/blob/master/v3/docs/">documentation</a>
200-
can help. Its code is open source on <a
209+
can help. Or check out its code at <a
201210
href="https://github.com/pgbovine/OnlinePythonTutor/">GitHub</a>.</p>
202211

203212
<p>Join the <a

0 commit comments

Comments
 (0)