~azzar1/unity/add-show-desktop-key

332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
1
/* IVLE - Informatics Virtual Learning Environment
2
 * Copyright (C) 2007-2008 The University of Melbourne
3
 *
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.
8
 *
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.
13
 *
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
17
 *
18
 * Module: Console (Client-side JavaScript)
19
 * Author: Tom Conway, Matt Giuca
20
 * Date: 30/1/2008
21
 */
22
432 by drtomc
usrmgt: more work on this. Still some work to go.
23
var server_key;
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
24
339 by mattgiuca
console:
25
/* Begin religious debate (tabs vs spaces) here: */
26
/* (This string will be inserted in the console when the user presses the Tab
27
 * key) */
28
TAB_STRING = "    ";
29
332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
30
/* Console DOM objects */
31
console_body = null;
32
console_filler = null;
33
339 by mattgiuca
console:
34
windowpane_mode = false;
343 by mattgiuca
console: Small refactoring of how server starts up. Currently does not affect
35
server_started = false;
339 by mattgiuca
console:
36
628 by drtomc
console: Add output based interrupt. This allows users to interrupt long
37
interrupted = false;
38
1340 by William Grant
Ensure that the console always restarts with the right cwd (cleaner reimplementation of r1333).
39
40
function get_console_start_directory()
41
{
42
    if((typeof(current_path) != 'undefined') && current_file)
43
    {
44
        // We have a current_path - give a suggestion to the server
45
        var path;
46
        if (current_file.isdir)
47
        {
48
            // Browser
49
            return path_join("/home", current_path);
50
        }
51
        else
52
        {
53
            // Editor - need to chop off filename
54
            var tmp_path = current_path.split('/');
55
            tmp_path.pop();
56
            return path_join("/home", tmp_path.join('/'));
57
        }
58
    }
59
    else
60
    {
61
        // No current_path - let the server decide
62
        return '';
63
    }
64
}
65
343 by mattgiuca
console: Small refactoring of how server starts up. Currently does not affect
66
/* Starts the console server, if it isn't already.
67
 * This can be called any number of times - it only starts the one server.
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
68
 * Note that this is asynchronous. It will return after signalling to start
69
 * the server, but there is no guarantee that it has been started yet.
343 by mattgiuca
console: Small refactoring of how server starts up. Currently does not affect
70
 * This is a separate step from console_init, as the server is only to be
71
 * started once the first command is entered.
72
 * Does not return a value. Writes to global variables
432 by drtomc
usrmgt: more work on this. Still some work to go.
73
 * server_host, and server_port.
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
74
 *
75
 * \param callback Function which will be called after the server has been
76
 * started. No parameters are passed. May be null.
217 by mattgiuca
Console: Python code generates a minimal document with a DIV and links to
77
 */
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
78
function start_server(callback)
217 by mattgiuca
Console: Python code generates a minimal document with a DIV and links to
79
{
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
80
    if (server_started)
81
    {
82
        callback();
83
        return;
84
    }
85
    var callback1 = function(xhr)
86
        {
87
            var json_text = xhr.responseText;
1477 by David Coles
Console: Show an error when the console fails to start. Really should be done
88
            try
89
            {
90
                server_key = JSON.parse(json_text).key;
91
                server_started = true;
92
                if (callback != null)
93
                    callback();
94
            }
95
            catch (e)
96
            {
97
                alert("An error occured when starting the IVLE console. " +
98
                    "Please refresh the page and try again.\n" +
99
                    "Details have been logged for further examination.")
100
            }
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
101
        }
872 by dcoles
Console: Allow console to be started with a set working directory (defaults to
102
1340 by William Grant
Ensure that the console always restarts with the right cwd (cleaner reimplementation of r1333).
103
    ajax_call(
104
        callback1, "console", "service",
105
        {"ivle.op": "start", "cwd": get_console_start_directory()}, 
106
        "POST");
217 by mattgiuca
Console: Python code generates a minimal document with a DIV and links to
107
}
108
332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
109
/** Initialises the console. All apps which import console are required to
110
 * call this function.
111
 * Optional "windowpane" (bool), if true, will cause the console to go into
112
 * "window pane" mode which will allow it to be opened and closed, and float
113
 * over the page.
114
 * (Defaults to closed).
115
 */
331 by mattgiuca
Console: Configured console to display properly as a "floating" window in the
116
function console_init(windowpane)
217 by mattgiuca
Console: Python code generates a minimal document with a DIV and links to
117
{
331 by mattgiuca
Console: Configured console to display properly as a "floating" window in the
118
    /* Set up the console as a floating pane */
332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
119
    console_body = document.getElementById("console_body");
362 by mattgiuca
console: Automatically focus input box when starting console app, or when
120
    /* If there is no console body, don't worry.
121
     * (This lets us import console.js even on pages without a console box */
122
    if (console_body == null) return;
332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
123
    console_filler = document.getElementById("console_filler");
331 by mattgiuca
Console: Configured console to display properly as a "floating" window in the
124
    if (windowpane)
339 by mattgiuca
console:
125
    {
126
        windowpane_mode = true;
332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
127
        console_minimize();
339 by mattgiuca
console:
128
    }
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
129
}
130
332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
131
/** Hide the main console panel, so the console minimizes to just an input box
132
 *  at the page bottom. */
133
function console_minimize()
134
{
339 by mattgiuca
console:
135
    if (!windowpane_mode) return;
332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
136
    console_body.setAttribute("class", "windowpane minimal");
137
    console_filler.setAttribute("class", "windowpane minimal");
138
}
139
140
/** Show the main console panel, so it enlarges out to its full size.
141
 */
142
function console_maximize()
143
{
339 by mattgiuca
console:
144
    if (!windowpane_mode) return;
332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
145
    console_body.setAttribute("class", "windowpane maximal");
146
    console_filler.setAttribute("class", "windowpane maximal");
147
}
148
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
149
/* current_text is the string currently on the command line.
150
 * If non-empty, it will be stored at the bottom of the history.
151
 */
152
function historyUp(current_text)
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
153
{
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
154
    /* Remember the changes made to this item */
155
    this.edited[this.cursor] = current_text;
156
    if (this.cursor > 0)
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
157
    {
158
        this.cursor--;
159
    }
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
160
    this.earliestCursor = this.cursor;
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
161
}
162
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
163
function historyDown(current_text)
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
164
{
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
165
    /* Remember the changes made to this item */
166
    this.edited[this.cursor] = current_text;
167
    if (this.cursor < this.items.length - 1)
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
168
    {
169
        this.cursor++;
170
    }
171
}
172
173
function historyCurr()
174
{
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
175
    return this.edited[this.cursor];
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
176
}
177
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
178
function historySubmit(text)
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
179
{
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
180
    /* Copy the selected item's "edited" version over the permanent version of
181
     * the last item. */
182
    this.items[this.items.length-1] = text;
183
    /* Add a new blank item */
184
    this.items[this.items.length] = "";
185
    this.cursor = this.items.length-1;
186
    /* Blow away all the edited versions, replacing them with the existing
187
     * items set.
188
     * Not the whole history - just start from the earliest edited one.
189
     * (This avoids slowdown over extended usage time).
190
     */
191
    for (var i=this.earliestCursor; i<=this.cursor; i++)
192
        this.edited[i] = this.items[i];
193
    this.earliestCursor = this.cursor;
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
194
}
195
196
function historyShow()
197
{
198
    var res = "";
199
    for (var i = 0; i < this.items.length; i++)
200
    {
201
        if (i == this.cursor)
202
        {
203
            res += "["
204
        }
205
        res += this.items[i].toString();
206
        if (i == this.cursor)
207
        {
208
            res += "]"
209
        }
210
        res += " "
211
    }
212
    if (this.cursor == this.items.length)
213
    {
214
        res += "[]";
215
    }
216
    return res;
217
}
218
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
219
/* How history works
220
 * This is a fairly complex mechanism due to complications when editing
221
 * history items. We store two arrays. "items" is the permanent history of
222
 * each item. "edited" is a "volatile" version of items - the edits made to
223
 * the history between now and last time you hit "enter".
224
 * This is because the user can go back and edit any of the previous items,
225
 * and the edits are remembered until they hit enter.
226
 *
227
 * When hitting enter, the "edited" version of the currently selected item
228
 * replaces the "item" version of the last item in the list.
229
 * Then a new blank item is created, for the new line of input.
230
 * Lastly, all the "edited" versions are replaced with their stable versions.
231
 *
232
 * Cursor never points to an invalid location.
233
 */
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
234
function History()
235
{
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
236
    this.items = new Array("");
237
    this.edited = new Array("");
238
    this.cursor = 0;
239
    this.earliestCursor = 0;
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
240
    this.up = historyUp;
241
    this.down = historyDown;
242
    this.curr = historyCurr;
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
243
    this.submit = historySubmit;
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
244
    this.show = historyShow;
245
}
246
247
var hist = new History();
248
628 by drtomc
console: Add output based interrupt. This allows users to interrupt long
249
function set_interrupt()
250
{
251
    interrupted = true;
252
}
253
254
function clear_output()
255
{
256
    var output = document.getElementById("console_output");
257
    while (output.firstChild)
258
    {
259
        output.removeChild(output.firstChild);
260
    }
261
}
262
333 by mattgiuca
console.js: enter_line now accepts the line as an argument instead of reading
263
/** Send a line of text to the Python server, wait for its return, and react
264
 * to its response by writing to the output box.
265
 * Also maximize the console window if not already.
266
 */
590 by mattgiuca
console: Added disabling of the input box when waiting for a response from the
267
function console_enter_line(inputbox, which)
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
268
{
628 by drtomc
console: Add output based interrupt. This allows users to interrupt long
269
    interrupted = false;
270
593 by mattgiuca
console.js: Fixed not working when you pass a string to console_enter_line
271
    if (typeof(inputbox) == "string")
272
    {
1153 by William Grant
In the console, append a newline to the end of a submitted block of code.
273
        var inputline = inputbox + "\n";
593 by mattgiuca
console.js: Fixed not working when you pass a string to console_enter_line
274
        inputbox = null;
275
    }
276
    else
277
    {
1099.5.3 by William Grant
Disable the console input textbox at the start of the submission process,
278
        /* Disable the text box */
279
        inputbox.setAttribute("disabled", "disabled");
280
1062 by wagrant
Console input from the text box now has a linefeed appended by the browser. We
281
        var inputline = inputbox.value + "\n";
593 by mattgiuca
console.js: Fixed not working when you pass a string to console_enter_line
282
    }
618 by drtomc
console: Get rid of all the extra pre elements.
283
    var output = document.getElementById("console_output");
284
    {
654 by mattgiuca
console.js|css:
285
        // Print ">>>" span
286
        var span = document.createElement("span");
287
        span.setAttribute("class", "inputPrompt");
1064 by wagrant
The browser console now uses the correct prompt in the log pane - previously
288
        span.appendChild(document.createTextNode(
1171 by William Grant
Replace all uses of .textContent with .nodeValue.
289
              document.getElementById("console_prompt").firstChild.nodeValue)
1064 by wagrant
The browser console now uses the correct prompt in the log pane - previously
290
                        );
654 by mattgiuca
console.js|css:
291
        output.appendChild(span);
292
        // Print input line itself in a span
618 by drtomc
console: Get rid of all the extra pre elements.
293
        var span = document.createElement("span");
294
        span.setAttribute("class", "inputMsg");
1062 by wagrant
Console input from the text box now has a linefeed appended by the browser. We
295
        span.appendChild(document.createTextNode(inputline));
618 by drtomc
console: Get rid of all the extra pre elements.
296
        output.appendChild(span);
297
    }
1340 by William Grant
Ensure that the console always restarts with the right cwd (cleaner reimplementation of r1333).
298
    var args = {
299
        "ivle.op": "chat", "kind": which, "key": server_key,
300
        "text": inputline, "cwd": get_console_start_directory()
301
        };
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
302
    var callback = function(xhr)
303
        {
1099.5.1 by William Grant
Disable the console input textbox properly, and don't set the colour
304
            console_response(inputbox, inputline, xhr.responseText);
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
305
        }
1099.1.29 by William Grant
ivle.webapp.console.service: Port www/apps/consoleservice to new framework.
306
    ajax_call(callback, "console", "service", args, "POST");
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
307
}
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
308
1099.5.1 by William Grant
Disable the console input textbox properly, and don't set the colour
309
function console_response(inputbox, inputline, responseText)
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
310
{
646 by drtomc
console: - work around the ff bug with the cursor.
311
    try
312
    {
313
        var res = JSON.parse(responseText);
314
    }
315
    catch (e)
316
    {
317
        alert("An internal error occurred in the python console.");
318
        return;
319
    }
328 by mattgiuca
console: Renamed HTML element IDs to prefix "console_".
320
    var output = document.getElementById("console_output");
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
321
    if (res.hasOwnProperty('okay'))
322
    {
991 by dcoles
Console: Some improvements to the python console code - most notably the
323
        // Success!
324
        if (res.okay)
325
        {
326
            output.appendChild(document.createTextNode(res.okay + "\n"));
327
            output.appendChild(span);
328
        }
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
329
        // set the prompt to >>>
991 by dcoles
Console: Some improvements to the python console code - most notably the
330
        set_prompt(">>>");
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
331
    }
332
    else if (res.hasOwnProperty('exc'))
333
    {
334
        // Failure!
335
        // print out the error message (res.exc)
991 by dcoles
Console: Some improvements to the python console code - most notably the
336
        print_error(res.exc);
337
        
654 by mattgiuca
console.js|css:
338
        // set the prompt to >>>
991 by dcoles
Console: Some improvements to the python console code - most notably the
339
        set_prompt(">>>");
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
340
    }
737 by dcoles
Console: The consoleservice is now able to work out when a console has timed
341
    else if (res.hasOwnProperty('restart') && res.hasOwnProperty('key'))
342
    {
343
        // Server has indicated that the console should be restarted
344
        
345
        // Get the new key (host, port, magic)
346
        server_key = res.key;
347
348
        // Print a reason to explain why we'd do such a horrible thing
349
        // (console timeout, server error etc.)
991 by dcoles
Console: Some improvements to the python console code - most notably the
350
        print_error("Console Restart: " + res.restart);
351
        
737 by dcoles
Console: The consoleservice is now able to work out when a console has timed
352
        // set the prompt to >>>
991 by dcoles
Console: Some improvements to the python console code - most notably the
353
        set_prompt(">>>");
737 by dcoles
Console: The consoleservice is now able to work out when a console has timed
354
    }
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
355
    else if (res.hasOwnProperty('more'))
356
    {
357
        // Need more input, so set the prompt to ...
991 by dcoles
Console: Some improvements to the python console code - most notably the
358
        set_prompt("...");
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
359
    }
598 by drtomc
console: send output back to the browser progressively.
360
    else if (res.hasOwnProperty('output'))
361
    {
599 by drtomc
console: improve end of line handling.
362
        if (res.output.length > 0)
598 by drtomc
console: send output back to the browser progressively.
363
        {
618 by drtomc
console: Get rid of all the extra pre elements.
364
            output.appendChild(document.createTextNode(res.output));
598 by drtomc
console: send output back to the browser progressively.
365
        }
366
        var callback = function(xhr)
367
            {
1099.5.1 by William Grant
Disable the console input textbox properly, and don't set the colour
368
                console_response(inputbox, null, xhr.responseText);
598 by drtomc
console: send output back to the browser progressively.
369
            }
628 by drtomc
console: Add output based interrupt. This allows users to interrupt long
370
        if (interrupted)
371
        {
372
            var kind = "interrupt";
373
        }
374
        else
375
        {
376
            var kind = "chat";
377
        }
1340 by William Grant
Ensure that the console always restarts with the right cwd (cleaner reimplementation of r1333).
378
        var args = {
379
            "ivle.op": "chat", "kind": kind, "key": server_key,
380
            "text": '', "cwd": get_console_start_directory()
381
            };
1099.1.29 by William Grant
ivle.webapp.console.service: Port www/apps/consoleservice to new framework.
382
        ajax_call(callback, "console", "service", args, "POST");
623 by drtomc
console: fix a minor styling flaw.
383
629 by drtomc
console: a couple of minor tweaks arising from conversation with Adrian.
384
        // Open up the console so we can see the output
385
        // FIXME: do we need to maximize here?
623 by drtomc
console: fix a minor styling flaw.
386
        console_maximize();
629 by drtomc
console: a couple of minor tweaks arising from conversation with Adrian.
387
623 by drtomc
console: fix a minor styling flaw.
388
        /* Auto-scrolling */
389
        divScroll.activeScroll();
390
598 by drtomc
console: send output back to the browser progressively.
391
        // Return early, so we don't re-enable the input box.
392
        return;
393
    }
991 by dcoles
Console: Some improvements to the python console code - most notably the
394
    else
395
    {
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
396
        // assert res.hasOwnProperty('input')
991 by dcoles
Console: Some improvements to the python console code - most notably the
397
        set_prompt("...");
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
398
    }
598 by drtomc
console: send output back to the browser progressively.
399
400
    if (inputbox != null)
401
    {
402
        /* Re-enable the text box */
403
        inputbox.removeAttribute("disabled");
628 by drtomc
console: Add output based interrupt. This allows users to interrupt long
404
        interrupted = false;
598 by drtomc
console: send output back to the browser progressively.
405
    }
406
332 by mattgiuca
console plugin: Now presents minimize/maximize buttons, allowing itself to be
407
    /* Open up the console so we can see the output */
408
    console_maximize();
616 by agdimech
/console/console.js: Added dynamic scrolling for the console.
409
    /* Auto-scrolling */
410
    divScroll.activeScroll();
629 by drtomc
console: a couple of minor tweaks arising from conversation with Adrian.
411
412
    // Focus the input box by default
991 by dcoles
Console: Some improvements to the python console code - most notably the
413
    document.getElementById("console_output").focus();
414
    document.getElementById("console_inputText").focus();
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
415
}
416
417
function catch_input(key)
418
{
328 by mattgiuca
console: Renamed HTML element IDs to prefix "console_".
419
    var inp = document.getElementById('console_inputText');
339 by mattgiuca
console:
420
    switch (key)
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
421
    {
339 by mattgiuca
console:
422
    case 9:                 /* Tab key */
423
        var selstart = inp.selectionStart;
424
        var selend = inp.selectionEnd;
425
        if (selstart == selend)
426
        {
427
            /* No selection, just a carat. Insert a tab here. */
428
            inp.value = inp.value.substr(0, selstart)
429
                + TAB_STRING + inp.value.substr(selstart);
430
        }
431
        else
432
        {
433
            /* Text is selected. Just indent the whole line
434
             * by inserting a tab at the start */
435
            inp.value = TAB_STRING + inp.value;
436
        }
437
        /* Update the selection so the same characters as before are selected
438
         */
439
        inp.selectionStart = selstart + TAB_STRING.length;
440
        inp.selectionEnd = inp.selectionStart + (selend - selstart);
441
        /* Cancel the event, so the TAB key doesn't move focus away from this
442
         * box */
443
        return false;
444
        /* Note: If it happens that some browsers don't support event
445
         * cancelling properly, this hack might work instead:
446
        setTimeout(
447
            "document.getElementById('console_inputText').focus()",
448
            0);
449
         */
450
        break;
451
    case 13:                /* Enter key */
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
452
        var callback = function()
453
        {
454
            /* Send the line of text to the server */
590 by mattgiuca
console: Added disabling of the input box when waiting for a response from the
455
            console_enter_line(inp, "chat");
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
456
            hist.submit(inp.value);
457
            inp.value = hist.curr();
458
        }
1341 by William Grant
Disable the console input textbox while starting the server.
459
460
        /* Disable the text box. This will be redone by
461
         * console_enter_line, but we do it here too in case start_server
462
         * takes a while.
463
         */
464
        inp.setAttribute("disabled", "disabled");
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
465
        /* Start the server if it hasn't already been started */
466
        start_server(callback);
339 by mattgiuca
console:
467
        break;
468
    case 38:                /* Up arrow */
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
469
        hist.up(inp.value);
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
470
        inp.value = hist.curr();
1308 by William Grant
Unbreak console history retrieval in IE/WebKit.
471
        /* Inhibit further responses to this event, or WebKit moves the
472
         * cursor to the start. */
473
        return false;
339 by mattgiuca
console:
474
        break;
475
    case 40:                /* Down arrow */
350 by mattgiuca
media/console/console.js: Rewrote console history storage, browsing, and
476
        hist.down(inp.value);
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
477
        inp.value = hist.curr();
1308 by William Grant
Unbreak console history retrieval in IE/WebKit.
478
        return false;
339 by mattgiuca
console:
479
        break;
276 by mattgiuca
Console now runs inside IVLE (without requiring an IFRAME). The separate
480
    }
217 by mattgiuca
Console: Python code generates a minimal document with a DIV and links to
481
}
616 by agdimech
/console/console.js: Added dynamic scrolling for the console.
482
991 by dcoles
Console: Some improvements to the python console code - most notably the
483
/** Resets the console by signalling the old console to expire and starting a 
484
 * new one.
485
 */
486
function console_reset()
487
{
488
    // FIXME: We show some feedback here - either disable input or at very 
489
    // least the reset button.
490
491
    // Restart the console
492
    if(!server_started)
493
    {
494
        start_server(null);
495
    }
496
    else
497
    {
1340 by William Grant
Ensure that the console always restarts with the right cwd (cleaner reimplementation of r1333).
498
        xhr = ajax_call(null, "console", "service", {"ivle.op": "chat", "kind": "terminate", "key": server_key, "cwd": get_console_start_directory()}, "POST");
1156 by William Grant
Remove an extra argument to console_response() in console_reset(). Fixes
499
        console_response(null, null, xhr.responseText);
991 by dcoles
Console: Some improvements to the python console code - most notably the
500
    }
501
}
502
503
/** Prints an error line in the console **/
504
function print_error(error)
505
{ 
506
    var output = document.getElementById("console_output");
507
  
508
    // Create text block
509
    var span = document.createElement("span");
510
    span.setAttribute("class", "errorMsg");
511
    span.appendChild(document.createTextNode(error + "\n"));
512
    output.appendChild(span);
513
514
    // Autoscroll
515
    divScroll.activeScroll();
516
}
517
518
/** Sets the prompt text **/
519
function set_prompt(prompt_text)
520
{
521
    var prompt = document.getElementById("console_prompt");
522
    prompt.replaceChild(document.createTextNode(prompt_text + " "), prompt.firstChild);
523
}
524
616 by agdimech
/console/console.js: Added dynamic scrolling for the console.
525
/**** Following Code modified from ******************************************/
526
/**** http://radio.javaranch.com/pascarello/2006/08/17/1155837038219.html ***/
527
/****************************************************************************/
528
var chatscroll = new Object();
529
530
chatscroll.Pane = function(scrollContainerId)
531
{
532
    this.scrollContainerId = scrollContainerId;
533
}
534
535
chatscroll.Pane.prototype.activeScroll = function()
536
{
537
    var scrollDiv = document.getElementById(this.scrollContainerId);
538
    var currentHeight = 0;
539
        
540
    if (scrollDiv.scrollHeight > 0)
541
        currentHeight = scrollDiv.scrollHeight;
991 by dcoles
Console: Some improvements to the python console code - most notably the
542
    else if (scrollDiv.offsetHeight > 0)
543
        currentHeight = scrollDiv.offsetHeight;
616 by agdimech
/console/console.js: Added dynamic scrolling for the console.
544
545
    scrollDiv.scrollTop = currentHeight;
546
547
    scrollDiv = null;
548
}
549
550
var divScroll = new chatscroll.Pane('console_output');