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