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

« back to all changes in this revision

Viewing changes to www/media/console/console.js

  • Committer: mattgiuca
  • Date: 2008-02-15 07:14:52 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:478
scripts/usrmgr-server: Renamed actions from dashes to underscores.
    (Consistency).
    accept_user returns a dict instead of None.

apps.py: Turned off auth for userservice (otherwise requests can't come thru
    from a user who is not activated; dispatch blocks such requests).
    Userservice does its own auth from now on.

userservice: Now makes the call to usrmgt-server for accept_me.
    Does authentication (since we can't do it at dispatch level).

tos.js: Clicking Accept now makes an Ajax call to userservice to get the
    account activated.

WHAT WORKS: Clicking the button now gets the account activated. There are some
    rough edges and errors won't be handled well.
WHAT DOESN'T: After clicking, the user is left thinking that nothing happened.
    They have to log out and back in again to enable themselves.
    (This is noted in the bug tracker).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
23
var server_key;
 
24
 
 
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
 
 
30
/* Console DOM objects */
 
31
console_body = null;
 
32
console_filler = null;
 
33
 
 
34
windowpane_mode = false;
 
35
server_started = false;
 
36
 
 
37
/* Starts the console server, if it isn't already.
 
38
 * This can be called any number of times - it only starts the one server.
 
39
 * This is a separate step from console_init, as the server is only to be
 
40
 * started once the first command is entered.
 
41
 * Does not return a value. Writes to global variables
 
42
 * server_host, and server_port.
 
43
 */
 
44
function start_server()
 
45
{
 
46
    if (server_started) return;
 
47
    var xhr = ajax_call("consoleservice", "start", {}, "POST");
 
48
    var json_text = xhr.responseText;
 
49
    server_key = JSON.parse(json_text);
 
50
    server_started = true;
 
51
}
 
52
 
 
53
/** Initialises the console. All apps which import console are required to
 
54
 * call this function.
 
55
 * Optional "windowpane" (bool), if true, will cause the console to go into
 
56
 * "window pane" mode which will allow it to be opened and closed, and float
 
57
 * over the page.
 
58
 * (Defaults to closed).
 
59
 */
 
60
function console_init(windowpane)
 
61
{
 
62
    /* Set up the console as a floating pane */
 
63
    console_body = document.getElementById("console_body");
 
64
    /* If there is no console body, don't worry.
 
65
     * (This lets us import console.js even on pages without a console box */
 
66
    if (console_body == null) return;
 
67
    console_filler = document.getElementById("console_filler");
 
68
    if (windowpane)
 
69
    {
 
70
        windowpane_mode = true;
 
71
        console_minimize();
 
72
    }
 
73
    /* TEMP: Start the server now.
 
74
     * Ultimately we want the server to start only when a line is typed, but
 
75
     * it currently does it asynchronously and doesn't start in time for the
 
76
     * first line. */
 
77
    start_server();
 
78
}
 
79
 
 
80
/** Hide the main console panel, so the console minimizes to just an input box
 
81
 *  at the page bottom. */
 
82
function console_minimize()
 
83
{
 
84
    if (!windowpane_mode) return;
 
85
    console_body.setAttribute("class", "windowpane minimal");
 
86
    console_filler.setAttribute("class", "windowpane minimal");
 
87
}
 
88
 
 
89
/** Show the main console panel, so it enlarges out to its full size.
 
90
 */
 
91
function console_maximize()
 
92
{
 
93
    if (!windowpane_mode) return;
 
94
    console_body.setAttribute("class", "windowpane maximal");
 
95
    console_filler.setAttribute("class", "windowpane maximal");
 
96
    /* Focus the input box by default */
 
97
    document.getElementById("console_inputText").focus()
 
98
}
 
99
 
 
100
/* current_text is the string currently on the command line.
 
101
 * If non-empty, it will be stored at the bottom of the history.
 
102
 */
 
103
function historyUp(current_text)
 
104
{
 
105
    /* Remember the changes made to this item */
 
106
    this.edited[this.cursor] = current_text;
 
107
    if (this.cursor > 0)
 
108
    {
 
109
        this.cursor--;
 
110
    }
 
111
    this.earliestCursor = this.cursor;
 
112
}
 
113
 
 
114
function historyDown(current_text)
 
115
{
 
116
    /* Remember the changes made to this item */
 
117
    this.edited[this.cursor] = current_text;
 
118
    if (this.cursor < this.items.length - 1)
 
119
    {
 
120
        this.cursor++;
 
121
    }
 
122
}
 
123
 
 
124
function historyCurr()
 
125
{
 
126
    return this.edited[this.cursor];
 
127
}
 
128
 
 
129
function historySubmit(text)
 
130
{
 
131
    /* Copy the selected item's "edited" version over the permanent version of
 
132
     * the last item. */
 
133
    this.items[this.items.length-1] = text;
 
134
    /* Add a new blank item */
 
135
    this.items[this.items.length] = "";
 
136
    this.cursor = this.items.length-1;
 
137
    /* Blow away all the edited versions, replacing them with the existing
 
138
     * items set.
 
139
     * Not the whole history - just start from the earliest edited one.
 
140
     * (This avoids slowdown over extended usage time).
 
141
     */
 
142
    for (var i=this.earliestCursor; i<=this.cursor; i++)
 
143
        this.edited[i] = this.items[i];
 
144
    this.earliestCursor = this.cursor;
 
145
}
 
146
 
 
147
function historyShow()
 
148
{
 
149
    var res = "";
 
150
    for (var i = 0; i < this.items.length; i++)
 
151
    {
 
152
        if (i == this.cursor)
 
153
        {
 
154
            res += "["
 
155
        }
 
156
        res += this.items[i].toString();
 
157
        if (i == this.cursor)
 
158
        {
 
159
            res += "]"
 
160
        }
 
161
        res += " "
 
162
    }
 
163
    if (this.cursor == this.items.length)
 
164
    {
 
165
        res += "[]";
 
166
    }
 
167
    return res;
 
168
}
 
169
 
 
170
/* How history works
 
171
 * This is a fairly complex mechanism due to complications when editing
 
172
 * history items. We store two arrays. "items" is the permanent history of
 
173
 * each item. "edited" is a "volatile" version of items - the edits made to
 
174
 * the history between now and last time you hit "enter".
 
175
 * This is because the user can go back and edit any of the previous items,
 
176
 * and the edits are remembered until they hit enter.
 
177
 *
 
178
 * When hitting enter, the "edited" version of the currently selected item
 
179
 * replaces the "item" version of the last item in the list.
 
180
 * Then a new blank item is created, for the new line of input.
 
181
 * Lastly, all the "edited" versions are replaced with their stable versions.
 
182
 *
 
183
 * Cursor never points to an invalid location.
 
184
 */
 
185
function History()
 
186
{
 
187
    this.items = new Array("");
 
188
    this.edited = new Array("");
 
189
    this.cursor = 0;
 
190
    this.earliestCursor = 0;
 
191
    this.up = historyUp;
 
192
    this.down = historyDown;
 
193
    this.curr = historyCurr;
 
194
    this.submit = historySubmit;
 
195
    this.show = historyShow;
 
196
}
 
197
 
 
198
var hist = new History();
 
199
 
 
200
/** Send a line of text to the Python server, wait for its return, and react
 
201
 * to its response by writing to the output box.
 
202
 * Also maximize the console window if not already.
 
203
 */
 
204
function console_enter_line(inputline, which)
 
205
{
 
206
    /* Start the server if it hasn't already been started */
 
207
    start_server();
 
208
    var args = {"key": server_key, "text":inputline};
 
209
    var xmlhttp = ajax_call("consoleservice", which, args, "POST");
 
210
 
 
211
    var res = JSON.parse(xmlhttp.responseText);
 
212
    var output = document.getElementById("console_output");
 
213
    {
 
214
        var pre = document.createElement("pre");
 
215
        pre.setAttribute("class", "inputMsg");
 
216
        pre.appendChild(document.createTextNode(inputline + "\n"));
 
217
        output.appendChild(pre);
 
218
    }
 
219
    if (res.hasOwnProperty('okay'))
 
220
    {
 
221
        // Success!
 
222
        // print out the output (res.okay[0])
 
223
        var pre = document.createElement("pre");
 
224
        pre.setAttribute("class", "outputMsg");
 
225
        pre.appendChild(document.createTextNode(res.okay[0]));
 
226
        output.appendChild(pre);
 
227
        // print out the return value (res.okay[1])
 
228
        if (res.okay[1])
 
229
        {
 
230
            var pre = document.createElement("pre");
 
231
            pre.setAttribute("class", "outputMsg");
 
232
            pre.appendChild(document.createTextNode(res.okay[1] + "\n"));
 
233
            output.appendChild(pre);
 
234
        }
 
235
        // set the prompt to >>>
 
236
        var prompt = document.getElementById("console_prompt");
 
237
        prompt.replaceChild(document.createTextNode(">>> "), prompt.firstChild);
 
238
    }
 
239
    else if (res.hasOwnProperty('exc'))
 
240
    {
 
241
        // Failure!
 
242
        // print out any output that came before the error
 
243
        if (res.exc[0].length > 0)
 
244
        {
 
245
            var pre = document.createElement("pre");
 
246
            pre.setAttribute("class", "outputMsg");
 
247
            pre.appendChild(document.createTextNode(res.exc[0]));
 
248
            output.appendChild(pre);
 
249
        }
 
250
 
 
251
        // print out the error message (res.exc)
 
252
        var pre = document.createElement("pre");
 
253
        pre.setAttribute("class", "errorMsg");
 
254
        pre.appendChild(document.createTextNode(res.exc[1]));
 
255
        output.appendChild(pre);
 
256
    }
 
257
    else if (res.hasOwnProperty('more'))
 
258
    {
 
259
        // Need more input, so set the prompt to ...
 
260
        var prompt = document.getElementById("console_prompt");
 
261
        prompt.replaceChild(document.createTextNode("... "), prompt.firstChild);
 
262
    }
 
263
    else {
 
264
        // assert res.hasOwnProperty('input')
 
265
        var prompt = document.getElementById("console_prompt");
 
266
        prompt.replaceChild(document.createTextNode("+++ "), prompt.firstChild);
 
267
    }
 
268
    /* Open up the console so we can see the output */
 
269
    console_maximize();
 
270
}
 
271
 
 
272
function catch_input(key)
 
273
{
 
274
    var inp = document.getElementById('console_inputText');
 
275
    switch (key)
 
276
    {
 
277
    case 9:                 /* Tab key */
 
278
        var selstart = inp.selectionStart;
 
279
        var selend = inp.selectionEnd;
 
280
        if (selstart == selend)
 
281
        {
 
282
            /* No selection, just a carat. Insert a tab here. */
 
283
            inp.value = inp.value.substr(0, selstart)
 
284
                + TAB_STRING + inp.value.substr(selstart);
 
285
        }
 
286
        else
 
287
        {
 
288
            /* Text is selected. Just indent the whole line
 
289
             * by inserting a tab at the start */
 
290
            inp.value = TAB_STRING + inp.value;
 
291
        }
 
292
        /* Update the selection so the same characters as before are selected
 
293
         */
 
294
        inp.selectionStart = selstart + TAB_STRING.length;
 
295
        inp.selectionEnd = inp.selectionStart + (selend - selstart);
 
296
        /* Cancel the event, so the TAB key doesn't move focus away from this
 
297
         * box */
 
298
        return false;
 
299
        /* Note: If it happens that some browsers don't support event
 
300
         * cancelling properly, this hack might work instead:
 
301
        setTimeout(
 
302
            "document.getElementById('console_inputText').focus()",
 
303
            0);
 
304
         */
 
305
        break;
 
306
    case 13:                /* Enter key */
 
307
        /* Send the line of text to the server */
 
308
        console_enter_line(inp.value, "chat");
 
309
        hist.submit(inp.value);
 
310
        inp.value = hist.curr();
 
311
        break;
 
312
    case 38:                /* Up arrow */
 
313
        hist.up(inp.value);
 
314
        inp.value = hist.curr();
 
315
        break;
 
316
    case 40:                /* Down arrow */
 
317
        hist.down(inp.value);
 
318
        inp.value = hist.curr();
 
319
        break;
 
320
    }
 
321
}