Manually merge changes from webpython branch.
This commit is contained in:
@ -20,6 +20,14 @@ $(function() {
|
||||
var qa_api = undefined;
|
||||
var output_mode_is_streaming = true;
|
||||
|
||||
var websocket,
|
||||
turtlescreen,
|
||||
numMessages = 0,
|
||||
turtlecanvas = $('#turtlecanvas'),
|
||||
prompt = $('#prompt'),
|
||||
commands = ['input', 'write', 'turtle', 'turtlebatch'],
|
||||
streams = ['stdin', 'stdout', 'stderr'];
|
||||
|
||||
var flowrResultHtml = '<div class="panel panel-default"><div id="{{headingId}}" role="tab" class="panel-heading"><h4 class="panel-title"><a data-toggle="collapse" data-parent="#flowrHint" href="#{{collapseId}}" aria-expanded="true" aria-controls="{{collapseId}}"></a></h4></div><div id="{{collapseId}}" role="tabpanel" aria-labelledby="{{headingId}}" class="panel-collapse collapse"><div class="panel-body"></div></div></div>'
|
||||
|
||||
var ajax = function(options) {
|
||||
@ -181,7 +189,13 @@ $(function() {
|
||||
};
|
||||
|
||||
var evaluateCodeWithStreamedResponse = function(url, callback) {
|
||||
var event_source = new EventSource(url);
|
||||
initWebsocketConnection(url);
|
||||
|
||||
// TODO only init turtle when required
|
||||
initTurtle();
|
||||
|
||||
// TODO reimplement via websocket messsages
|
||||
/*var event_source = new EventSource(url);
|
||||
|
||||
event_source.addEventListener('close', closeEventSource);
|
||||
event_source.addEventListener('error', closeEventSource);
|
||||
@ -201,7 +215,7 @@ $(function() {
|
||||
|
||||
event_source.addEventListener('status', function(event) {
|
||||
showStatus(JSON.parse(event.data));
|
||||
});
|
||||
});*/
|
||||
};
|
||||
|
||||
var handleStreamedResponseForCodePilot = function(event) {
|
||||
@ -428,7 +442,7 @@ $(function() {
|
||||
handleSidebarClick(e);
|
||||
});
|
||||
*/
|
||||
|
||||
|
||||
//session
|
||||
session.on('annotationRemoval', handleAnnotationRemoval);
|
||||
session.on('annotationChange', handleAnnotationChange);
|
||||
@ -1065,6 +1079,183 @@ $(function() {
|
||||
$('#request-for-comments').toggle(isActiveFileSubmission() && !isActiveFileBinary());
|
||||
};
|
||||
|
||||
var initWebsocketConnection = function(url) {
|
||||
websocket = new WebSocket('ws://' + window.location.hostname + ':' + window.location.port + url);
|
||||
websocket.onopen = function(evt) { onWebSocketOpen(evt) };
|
||||
websocket.onclose = function(evt) { onWebSocketClose(evt) };
|
||||
websocket.onmessage = function(evt) { onWebSocketMessage(evt) };
|
||||
websocket.onerror = function(evt) { onWebSocketError(evt) };
|
||||
websocket.flush = function() { this.send('\n'); }
|
||||
};
|
||||
|
||||
var initTurtle = function() {
|
||||
turtlescreen = new Turtle(websocket, $('#turtlecanvas'));
|
||||
};
|
||||
|
||||
var initCallbacks = function() {
|
||||
if ($('#run').isPresent()) {
|
||||
$('#run').bind('click', function(event) {
|
||||
hideCanvas();
|
||||
hidePrompt();
|
||||
});
|
||||
}
|
||||
if ($('#prompt').isPresent()) {
|
||||
$('#prompt').on('keypress', handlePromptKeyPress);
|
||||
$('#prompt-submit').on('click', submitPromptInput);
|
||||
}
|
||||
}
|
||||
|
||||
var onWebSocketOpen = function(evt) {
|
||||
//alert("Session started");
|
||||
};
|
||||
|
||||
var onWebSocketClose = function(evt) {
|
||||
//alert("Session terminated");
|
||||
};
|
||||
|
||||
var onWebSocketMessage = function(evt) {
|
||||
numMessages++;
|
||||
parseCanvasMessage(evt.data, true);
|
||||
};
|
||||
|
||||
var onWebSocketError = function(evt) {
|
||||
//alert("Something went wrong.")
|
||||
};
|
||||
|
||||
var executeCommand = function(msg) {
|
||||
if ($.inArray(msg.cmd, commands) == -1) {
|
||||
console.log("Unknown command: " + msg.cmd);
|
||||
// skipping unregistered commands is required
|
||||
// as we may receive mirrored response due to internal behaviour
|
||||
return;
|
||||
}
|
||||
switch(msg.cmd) {
|
||||
case 'input':
|
||||
showPrompt();
|
||||
break;
|
||||
case 'write':
|
||||
printWebsocketOutput(msg);
|
||||
break;
|
||||
case 'turtle':
|
||||
showCanvas();
|
||||
handleTurtleCommand(msg);
|
||||
break;
|
||||
case 'turtlebatch':
|
||||
showCanvas();
|
||||
handleTurtlebatchCommand(msg);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// todo reuse method from editor.js
|
||||
var printWebsocketOutput = function(msg) {
|
||||
var element = findOrCreateOutputElement(0);
|
||||
console.log(element);
|
||||
switch (msg.stream) {
|
||||
case 'internal':
|
||||
element.addClass('text-danger');
|
||||
break;
|
||||
case 'stderr':
|
||||
element.addClass('text-warning');
|
||||
break;
|
||||
case 'stdout':
|
||||
case 'stdin': // for eventual prompts
|
||||
default:
|
||||
element.addClass('text-muted');
|
||||
}
|
||||
element.append(msg.data)
|
||||
};
|
||||
|
||||
var handleTurtleCommand = function(msg) {
|
||||
if (msg.action in turtlescreen) {
|
||||
result = turtlescreen[msg.action].apply(turtlescreen, msg.args);
|
||||
websocket.send(JSON.stringify({cmd: 'result', 'result': result}));
|
||||
} else {
|
||||
websocket.send(JSON.stringify({cmd: 'exception', exception: 'AttributeError', message: msg.action}));
|
||||
}
|
||||
websocket.flush();
|
||||
};
|
||||
|
||||
var handleTurtlebatchCommand = function(msg) {
|
||||
for (i = 0; i < msg.batch.length; i++) {
|
||||
cmd = msg.batch[i];
|
||||
turtlescreen[cmd[0]].apply(turtlescreen, cmd[1]);
|
||||
}
|
||||
};
|
||||
|
||||
var handlePromptKeyPress = function(evt) {
|
||||
if (evt.which === ENTER_KEY_CODE) {
|
||||
submitPromptInput();
|
||||
}
|
||||
}
|
||||
|
||||
var submitPromptInput = function() {
|
||||
var input = $('#prompt-input');
|
||||
var message = input.val();
|
||||
websocket.send(JSON.stringify({cmd: 'result', 'data': message}));
|
||||
websocket.flush();
|
||||
input.val('');
|
||||
hidePrompt();
|
||||
}
|
||||
|
||||
var parseCanvasMessage = function(message, recursive) {
|
||||
var msg;
|
||||
message = message.replace(/^\s+|\s+$/g, "");
|
||||
try {
|
||||
// todo validate json instead of catching
|
||||
msg = JSON.parse(message);
|
||||
} catch (e) {
|
||||
if (!recursive) {
|
||||
return false;
|
||||
}
|
||||
// why does docker sometimes send multiple commands at once?
|
||||
message = message.replace(/^\s+|\s+$/g, "");
|
||||
messages = message.split("\n");
|
||||
for (var i = 0; i < messages.length; i++) {
|
||||
if (!messages[i]) {
|
||||
continue;
|
||||
}
|
||||
parseCanvasMessage(messages[i], false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
executeCommand(msg);
|
||||
};
|
||||
|
||||
var showPrompt = function() {
|
||||
if (prompt.isPresent() && prompt.hasClass('hidden')) {
|
||||
prompt.removeClass('hidden');
|
||||
}
|
||||
prompt.focus();
|
||||
}
|
||||
|
||||
var hidePrompt = function() {
|
||||
if (prompt.isPresent() && !prompt.hasClass('hidden')) {
|
||||
console.log("hiding prompt2");
|
||||
prompt.addClass('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
var showCanvas = function() {
|
||||
if ($('#turtlediv').isPresent()
|
||||
&& turtlecanvas.hasClass('hidden')) {
|
||||
// initialize two-column layout
|
||||
$('#output-col1').addClass('col-lg-7 col-md-7 two-column');
|
||||
turtlecanvas.removeClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
var hideCanvas = function() {
|
||||
if ($('#turtlediv').isPresent()
|
||||
&& !(turtlecanvas.hasClass('hidden'))) {
|
||||
output = $('#output-col1');
|
||||
if (output.hasClass('two-column')) {
|
||||
output.removeClass('col-lg-7 col-md-7 two-column');
|
||||
}
|
||||
turtlecanvas.addClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
var requestComments = function(e) {
|
||||
var user_id = $('#editor').data('user-id')
|
||||
var exercise_id = $('#editor').data('exercise-id')
|
||||
|
Reference in New Issue
Block a user