1
/* IVLE - Informatics Virtual Learning Environment
2
* Copyright (C) 2007-2008 The University of Melbourne
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
* Module: Console (Client-side JavaScript)
19
* Author: Tom Conway, Matt Giuca
23
digest_constant = "hello";
29
/* Begin religious debate (tabs vs spaces) here: */
30
/* (This string will be inserted in the console when the user presses the Tab
34
/* Console DOM objects */
36
console_filler = null;
38
windowpane_mode = false;
40
/* Starts the console server.
41
* Returns an object with fields "host", "port", "magic" describing the
44
function start_server()
46
var xhr = ajax_call("consoleservice", "start", {}, "POST");
47
var json_text = xhr.responseText;
48
return JSON.parse(json_text);
51
/** Initialises the console. All apps which import console are required to
53
* Optional "windowpane" (bool), if true, will cause the console to go into
54
* "window pane" mode which will allow it to be opened and closed, and float
56
* (Defaults to closed).
58
function console_init(windowpane)
60
/* Set up the console as a floating pane */
61
console_body = document.getElementById("console_body");
62
console_filler = document.getElementById("console_filler");
65
windowpane_mode = true;
68
/* Start the server */
69
var server_info = start_server();
70
server_host = server_info.host;
71
server_port = server_info.port;
72
server_magic = server_info.magic;
75
/** Hide the main console panel, so the console minimizes to just an input box
76
* at the page bottom. */
77
function console_minimize()
79
if (!windowpane_mode) return;
80
console_body.setAttribute("class", "windowpane minimal");
81
console_filler.setAttribute("class", "windowpane minimal");
84
/** Show the main console panel, so it enlarges out to its full size.
86
function console_maximize()
88
if (!windowpane_mode) return;
89
console_body.setAttribute("class", "windowpane maximal");
90
console_filler.setAttribute("class", "windowpane maximal");
93
/* Below here imported from trunk/console/console.js
101
if (this.cursor >= 0)
107
function historyDown()
109
if (this.cursor < this.items.length)
115
function historyCurr()
117
if (this.cursor < 0 || this.cursor >= this.items.length)
121
return this.items[this.cursor];
124
function historyAdd(text)
126
this.items[this.items.length] = text;
127
this.cursor = this.items.length;
130
function historyShow()
133
if (this.cursor == -1)
137
for (var i = 0; i < this.items.length; i++)
139
if (i == this.cursor)
143
res += this.items[i].toString();
144
if (i == this.cursor)
150
if (this.cursor == this.items.length)
159
this.items = new Array();
162
this.down = historyDown;
163
this.curr = historyCurr;
164
this.add = historyAdd;
165
this.show = historyShow;
168
var hist = new History();
170
/** Send a line of text to the Python server, wait for its return, and react
171
* to its response by writing to the output box.
172
* Also maximize the console window if not already.
174
function console_enter_line(inputline)
176
var digest = hex_md5(inputline + magic);
177
var args = {"host": server_host, "port": server_port,
178
"digest":digest, "text":inputline};
179
var xmlhttp = ajax_call("consoleservice", "chat", args, "POST");
181
var res = JSON.parse(xmlhttp.responseText);
182
var output = document.getElementById("console_output");
184
var pre = document.createElement("pre");
185
pre.setAttribute("class", "inputMsg");
186
pre.appendChild(document.createTextNode(inputline + "\n"));
187
output.appendChild(pre);
189
if (res.hasOwnProperty('okay'))
192
// print out the output (res.okay[0])
193
var pre = document.createElement("pre");
194
pre.setAttribute("class", "outputMsg");
195
pre.appendChild(document.createTextNode(res.okay[0]));
196
output.appendChild(pre);
197
// print out the return value (res.okay[1])
200
var pre = document.createElement("pre");
201
pre.setAttribute("class", "outputMsg");
202
pre.appendChild(document.createTextNode(res.okay[1] + "\n"));
203
output.appendChild(pre);
205
// set the prompt to >>>
206
var prompt = document.getElementById("console_prompt");
207
prompt.replaceChild(document.createTextNode(">>> "), prompt.firstChild);
209
else if (res.hasOwnProperty('exc'))
212
// print out the error message (res.exc)
213
var pre = document.createElement("pre");
214
pre.setAttribute("class", "errorMsg");
215
pre.appendChild(document.createTextNode(res.exc));
216
output.appendChild(pre);
218
else if (res.hasOwnProperty('more'))
220
// Need more input, so set the prompt to ...
221
var prompt = document.getElementById("console_prompt");
222
prompt.replaceChild(document.createTextNode("... "), prompt.firstChild);
225
// assert res.hasOwnProperty('input')
226
var prompt = document.getElementById("console_prompt");
227
prompt.replaceChild(document.createTextNode("+++ "), prompt.firstChild);
229
/* Open up the console so we can see the output */
233
function catch_input(key)
235
var inp = document.getElementById('console_inputText');
238
case 9: /* Tab key */
239
var selstart = inp.selectionStart;
240
var selend = inp.selectionEnd;
241
if (selstart == selend)
243
/* No selection, just a carat. Insert a tab here. */
244
inp.value = inp.value.substr(0, selstart)
245
+ TAB_STRING + inp.value.substr(selstart);
249
/* Text is selected. Just indent the whole line
250
* by inserting a tab at the start */
251
inp.value = TAB_STRING + inp.value;
253
/* Update the selection so the same characters as before are selected
255
inp.selectionStart = selstart + TAB_STRING.length;
256
inp.selectionEnd = inp.selectionStart + (selend - selstart);
257
/* Cancel the event, so the TAB key doesn't move focus away from this
260
/* Note: If it happens that some browsers don't support event
261
* cancelling properly, this hack might work instead:
263
"document.getElementById('console_inputText').focus()",
267
case 13: /* Enter key */
268
/* Send the line of text to the server */
269
console_enter_line(inp.value);
271
inp.value = hist.curr();
273
case 38: /* Up arrow */
275
inp.value = hist.curr();
277
case 40: /* Down arrow */
279
inp.value = hist.curr();