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