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

209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
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: Listing (File Browser, client)
19
 * Author: Matt Giuca
20
 * Date: 13/1/2008
21
 *
22
 * Handles directory listings on the client side.
23
 */
24
234 by mattgiuca
browser/listing.js:
25
/* Note: The DOM "tr" nodes of the file listing have extra attributes added
235 by mattgiuca
listing.js: Added sorting functions and a bit of infrastructure to facilitate
26
 * to them:
27
 *  filename: String.
28
 *  fileinfo: The file object as returned by the server.
29
 */
215 by mattgiuca
listing.js:
30
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
31
/* DOM nodeType constants */
32
ELEMENT_NODE = 1;
33
240 by mattgiuca
browser/listing.js: Wrote real comparison function and set up sort_order array
34
/** The current sort order (a list of fields to sort by, in order of
35
 * priority), and whether it is ascending or descending. */
36
sort_order = [];
37
sort_ascending = true;
38
229 by mattgiuca
Images: Reduced "small" icons from 22x22 to 16x16. Reduced "large" icons from
39
/** The width/height of filetype, svnstatus and publishstatus icons */
40
icon_size = 16;
41
215 by mattgiuca
listing.js:
42
/** ACTIONS **/
43
44
function action_rename(fromfilename)
45
{
683 by mattgiuca
browser/listing.js: When the "rename" dialog comes up, the default text is
46
    var tofilename = prompt("Rename file \"" + fromfilename + "\" to?",
47
        fromfilename);
215 by mattgiuca
listing.js:
48
    if (tofilename == null) return;
49
    do_action("move", current_path, {"from":fromfilename, "to":tofilename});
50
    return false;
51
}
52
921 by wagrant
fileservice_lib, browser: Rename the old remove action to delete, to
53
function action_delete(files)
215 by mattgiuca
listing.js:
54
{
614 by mattgiuca
browser/listing: Added a confirmation message for deleting files
55
    var conf_msg;
56
    /* A heavy nesty bit of logic to determine the confirmation message.
57
     */
58
    if (files.length == 0)
59
        return;
60
    else if (files.length == 1)
61
    {
62
        if (file_listing[files[0]].isdir)
63
            conf_msg = "Are you sure you want to delete the directory \""
64
                + files[0] + "\"?\n"
65
                + "All of the files in this directory will be lost.";
66
        else
67
            conf_msg = "Are you sure you want to delete the file \""
68
                + files[0] + "\"?";
69
    }
70
    else
71
    {
72
        var confirm_filelist = "";
73
        var num_dirs = 0;
74
        for (var i=0; i<files.length; i++)
75
        {
76
            if (file_listing[files[i]].isdir)
77
                num_dirs++;
78
            confirm_filelist += "  - " + files[i] + "\n";
79
        }
80
        conf_msg = "Are you sure you want to delete all of the "
81
            + "following ";
82
        if (num_dirs > 0)
83
        {
84
            if (files.length == num_dirs)
85
                conf_msg += "directories";
86
            else
87
                conf_msg += "files and directories";
88
        }
89
        else
90
            conf_msg += "files";
91
        conf_msg += ":\n" + confirm_filelist;
92
        if (num_dirs > 0)
93
            conf_msg += "\nAll of the files in these directories "
94
                     + "will be lost.";
95
    }
96
    /* Now we have the conf message */
97
98
    var confirmed = confirm(conf_msg);
99
    if (!confirmed) return;
921 by wagrant
fileservice_lib, browser: Rename the old remove action to delete, to
100
    do_action("delete", current_path, {"path":files});
215 by mattgiuca
listing.js:
101
    return false;
102
}
103
592 by mattgiuca
fileservice, browser/listing: Added new fileservice action, "mkdir".
104
function action_mkdir()
105
{
106
    var path = prompt("New directory name?");
107
    if (path == null) return;
108
    do_action("mkdir", current_path, {"path":path});
109
    return false;
110
}
111
611 by mattgiuca
"New File" now works. (This is a MUCH better replacement for having to go to
112
function action_newfile()
113
{
114
    var path = prompt("New file name?");
115
    if (path == null) return;
116
    /* "Upload" a blank file */
787 by mattgiuca
fileservice_lib/action.py:
117
    /* Note: "overwrite" defaults to false, so will error if it already
118
     * exists. */
611 by mattgiuca
"New File" now works. (This is a MUCH better replacement for having to go to
119
    do_action("putfile", current_path, {"path":path, "data":""});
120
    return false;
121
}
122
653 by mattgiuca
browser/listing: Rewrote cut/copy/paste actions to conform to the
123
/* Mode is either "copy" or "move".
124
 */
125
function action_copy_or_cut(files, mode)
126
{
127
    /* Store the "clipboard" in the browser cookie */
128
    var clip_obj = {"src": current_path, "file": files, "mode": mode};
129
    write_cookie("clipboard", clip_obj);
130
}
131
215 by mattgiuca
listing.js:
132
function action_copy(files)
133
{
653 by mattgiuca
browser/listing: Rewrote cut/copy/paste actions to conform to the
134
    action_copy_or_cut(files, "copy");
215 by mattgiuca
listing.js:
135
    return false;
136
}
137
138
function action_cut(files)
139
{
653 by mattgiuca
browser/listing: Rewrote cut/copy/paste actions to conform to the
140
    action_copy_or_cut(files, "move");
215 by mattgiuca
listing.js:
141
    return false;
142
}
143
144
function action_paste()
145
{
653 by mattgiuca
browser/listing: Rewrote cut/copy/paste actions to conform to the
146
    /* Get the "clipboard" object from the browser cookie */
147
    var clip_obj = read_cookie("clipboard");
148
    if (clip_obj == null)
149
    {
150
        alert("No files have been cut or copied.");
151
        return false;
152
    }
153
    /* The clip_obj is exactly what we want to pass, plus the current path
154
     * as destination. */
155
    clip_obj.dst = ".";
156
    do_action("paste", current_path, clip_obj);
215 by mattgiuca
listing.js:
157
    return false;
158
}
159
219 by mattgiuca
Browser.js: Added handlers for subversion actions.
160
function action_add(files)
161
{
162
    do_action("svnadd", current_path, {"path":files});
163
    return false;
164
}
165
921 by wagrant
fileservice_lib, browser: Rename the old remove action to delete, to
166
function action_remove(files)
167
{
168
    do_action("svnremove", current_path, {"path":files});
169
    return false;
170
}
171
219 by mattgiuca
Browser.js: Added handlers for subversion actions.
172
function action_revert(files)
173
{
174
    do_action("svnrevert", current_path, {"path":files});
175
    return false;
176
}
177
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
178
function action_publish(files)
179
{
726 by dcoles
Browser: Added code to allow directories to be published through the UI. Also
180
    do_action("publish", current_path, {"path":files});
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
181
    return false;
182
}
183
184
function action_unpublish(files)
185
{
727 by dcoles
Browser: Added UI code to let you publish and unpublish folders
186
    do_action("unpublish", current_path, {"path":files});
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
187
    return false;
188
}
189
918 by wagrant
browser: Expose svn update functionality. This brings a need for an
190
function action_update(files)
191
{
192
    if (files.length == 0) files = ".";
193
    do_action("svnupdate", current_path, {"path": files});
194
    return false;
195
}
196
919 by wagrant
fileservice_lib: Implement "svn resolved".
197
function action_resolved(files)
198
{
199
    if (files.length == 0) files = ".";
200
    do_action("svnresolved", current_path, {"path": files});
201
    return false;
202
}
203
219 by mattgiuca
Browser.js: Added handlers for subversion actions.
204
function action_commit(files)
205
{
206
    /* Get a commit log from the user */
207
    var logmsg = prompt("Enter commit log:");
223 by mattgiuca
util.js: Added "urlencode_path" which is specially designed to encode paths.
208
    if (logmsg == null) return;
219 by mattgiuca
Browser.js: Added handlers for subversion actions.
209
    do_action("svncommit", current_path, {"path":files, "logmsg": logmsg});
210
    return false;
211
}
212
613 by mattgiuca
browser/listing.js: Added action_selectall which can either select all or
213
/** Selects or deselects all files in the listing.
214
 * selected: true or false (defaults to true).
215
 * If false, deselects instead of selecting.
216
 */
217
function action_selectall(selected)
218
{
219
    if (selected == null)
220
        selected = true;
221
    /* Iterate through and check all the boxes.
222
     * Then update.
223
     * (We do this through the DOM because that is the authority that
224
     * update_selection uses to identify what is selected).
225
     */
226
    var files_children = document.getElementById("files").childNodes;
227
    for (var i=0; i<files_children.length; i++)
228
    {
229
        tr = files_children[i];
230
        tr.firstChild.firstChild.checked = selected;
231
    }
232
    update_selection();
233
}
234
387 by mattgiuca
Implemented file uploads.
235
/* Shows or hides the "upload panel" in the side panel.
236
 * toshow is true for showing, false for hiding.
237
 */
388 by mattgiuca
browser/listing: Upload button now toggles the upload panel instead of just
238
uploadpanel_shown = false;
387 by mattgiuca
Implemented file uploads.
239
function show_uploadpanel(toshow)
240
{
388 by mattgiuca
browser/listing: Upload button now toggles the upload panel instead of just
241
    if (toshow == null)
242
        uploadpanel_shown = !uploadpanel_shown;
243
    else
244
        uploadpanel_shown = toshow;
387 by mattgiuca
Implemented file uploads.
245
    document.getElementById("uploadpanel").setAttribute("style",
388 by mattgiuca
browser/listing: Upload button now toggles the upload panel instead of just
246
        "display: " + (uploadpanel_shown ? "auto" : "none") + ";");
387 by mattgiuca
Implemented file uploads.
247
    return false;
248
}
249
215 by mattgiuca
listing.js:
250
/** END ACTIONS **/
251
597 by mattgiuca
Major refactor of actions in File browser.
252
/** Updates the side-panel AND the actions in the top-bar. Expects selected_files
253
 * reflects the current selected files.
211 by mattgiuca
fileservice/listing: Slight change to date format.
254
 */
255
function update_sidepanel(total_file_size_sel)
256
{
257
    var sidepanel = document.getElementById("sidepanel");
258
    var filename;
259
    var file;
260
    var p;
387 by mattgiuca
Implemented file uploads.
261
    var div;
211 by mattgiuca
fileservice/listing: Slight change to date format.
262
    /* Is this dir under svn? */
602 by mattgiuca
util.js: Added shallow_copy_object function.
263
    var under_subversion = "svnstatus" in current_file;
211 by mattgiuca
fileservice/listing: Slight change to date format.
264
    dom_removechildren(sidepanel);
265
    if (selected_files.length <= 1)
266
    {
267
        if (selected_files.length == 0)
268
        {
269
            /* Display information about the current directory instead */
270
            filename = path_basename(current_path);
602 by mattgiuca
util.js: Added shallow_copy_object function.
271
            file = current_file;
211 by mattgiuca
fileservice/listing: Slight change to date format.
272
        }
273
        else if (selected_files.length == 1)
274
        {
215 by mattgiuca
listing.js:
275
            filename = selected_files[0];
211 by mattgiuca
fileservice/listing: Slight change to date format.
276
            file = file_listing[filename];
277
        }
278
        var filetype;
279
        if ("isdir" in file && file.isdir)
280
            filetype = "text/directory";
281
        else if ("type" in file)
282
            filetype = file.type;
283
        else
284
            filetype = "text/plain";
285
213 by mattgiuca
Fileservice / Files (Python and JS files):
286
        if ("type_nice" in file)
287
            filetype_nice = file.type_nice;
288
        else
289
            filetype_nice = "File";
290
211 by mattgiuca
fileservice/listing: Slight change to date format.
291
        p = document.createElement("p");
292
        sidepanel.appendChild(p);
293
        p.appendChild(dom_make_img(mime_type_to_icon(filetype, true),
294
            null, null, filetype));
295
        p = dom_make_text_elem("h2", filename);
296
        sidepanel.appendChild(p);
213 by mattgiuca
Fileservice / Files (Python and JS files):
297
        p = dom_make_text_elem("p", filetype_nice);
211 by mattgiuca
fileservice/listing: Slight change to date format.
298
        sidepanel.appendChild(p);
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
299
        var mini_icons = document.createElement("p");
300
        sidepanel.appendChild(mini_icons);
301
        var icon;
213 by mattgiuca
Fileservice / Files (Python and JS files):
302
        if (under_subversion)
303
        {
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
304
            icon = svnstatus_to_icon(file.svnstatus);
230 by mattgiuca
Removed "unversioned" icon from subversion status. Now unversioned files do
305
            if (icon)
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
306
                mini_icons.appendChild(dom_make_img(icon, icon_size, icon_size,
230 by mattgiuca
Removed "unversioned" icon from subversion status. Now unversioned files do
307
                    svnstatus_to_string(file.svnstatus)));
213 by mattgiuca
Fileservice / Files (Python and JS files):
308
            p = dom_make_text_elem("p", svnstatus_to_string(file.svnstatus));
309
            sidepanel.appendChild(p);
310
        }
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
311
        if ("published" in file && file.published)
312
        {
313
            icon = make_path(path_join(published_icon));
314
            if (icon)
315
            {
316
                if (mini_icons.childNodes.length > 0)
317
                    mini_icons.appendChild(document.createTextNode(" "));
318
                mini_icons.appendChild(dom_make_img(icon, icon_size, icon_size,
327 by mattgiuca
browser: Renamed "Published directory" label to "Published to the web".
319
                    "Published to the web"));
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
320
            }
327 by mattgiuca
browser: Renamed "Published directory" label to "Published to the web".
321
            p = dom_make_text_elem("p", "Published to the web");
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
322
            p.setAttribute("title",
323
                "Anybody on the web can view the files in this directory.");
324
            sidepanel.appendChild(p);
325
        }
326
        /* If we never wrote any mini-icons, remove this element */
327
        if (mini_icons.childNodes.length == 0)
328
            sidepanel.removeChild(mini_icons);
211 by mattgiuca
fileservice/listing: Slight change to date format.
329
        if ("size" in file)
330
        {
331
            p = dom_make_text_elem("p", "Size: " + nice_filesize(file.size));
332
            sidepanel.appendChild(p);
333
        }
334
        if ("mtime_nice" in file)
335
        {
608 by mattgiuca
browser/listing: REMOVED the generation of all action links to the right
336
            /* Break into lines on comma (separating date from time) */
337
            filetime_lines = file.mtime_nice.split(",");
338
            p = document.createElement("p");
339
            p.appendChild(document.createTextNode("Modified:"));
340
            for (var i=0; i<filetime_lines.length; i++)
341
            {
342
                p.appendChild(document.createElement("br"));
343
                p.appendChild(document.createTextNode(filetime_lines[i]));
344
            }
211 by mattgiuca
fileservice/listing: Slight change to date format.
345
            sidepanel.appendChild(p);
346
        }
347
    }
348
    else
349
    {
350
        /* Multiple files selected */
351
        p = document.createElement("p");
352
        sidepanel.appendChild(p);
353
        p.appendChild(dom_make_img(
224 by mattgiuca
util.js: Removed urlencoding support from "encoded_app_path" (now called
354
            app_path(type_icons_path_large, "multi.png"),
211 by mattgiuca
fileservice/listing: Slight change to date format.
355
            null, null, "Multiple files"));
356
        p = dom_make_text_elem("h2",
357
            selected_files.length.toString() + " files selected");
358
        sidepanel.appendChild(p);
359
        p = dom_make_text_elem("p", "Total size: "
360
            + nice_filesize(total_file_size_sel));
361
        sidepanel.appendChild(p);
362
    }
363
}
210 by mattgiuca
File browser: listing.js - The status bar is now updated whenever the
364
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
365
/** Updates the side-panel and status bar to reflect the current set of
366
 * selected files. This is done by inspecting the states of the check boxes.
367
 * Also changes the styling to highlight selected files.
368
 */
369
function update_selection()
370
{
371
    /* First get a list of all files that are selected, and
372
     * reset the styling on each file's row. */
373
    var files_children = document.getElementById("files").childNodes;
374
    var tr;
375
    var checkbox;
376
    var row_toggle = 1;
377
    selected_files = [];  /* Clear global selected_files */
210 by mattgiuca
File browser: listing.js - The status bar is now updated whenever the
378
379
    var total_file_size = 0;    /* In bytes */
380
    var total_file_size_sel = 0;
381
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
382
    /* Children are trs */
237 by mattgiuca
listing: bugfix, update_selection no longer dependent on dictionary ordering
383
    var filename;
210 by mattgiuca
File browser: listing.js - The status bar is now updated whenever the
384
    var file;
385
    if (file_listing == null) return;
237 by mattgiuca
listing: bugfix, update_selection no longer dependent on dictionary ordering
386
    for (var i=0; i<files_children.length; i++)
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
387
    {
237 by mattgiuca
listing: bugfix, update_selection no longer dependent on dictionary ordering
388
        filename = files_children[i].filename;
389
        file = files_children[i].fileinfo;
390
        /* Count total file size so we can write to the status bar later
210 by mattgiuca
File browser: listing.js - The status bar is now updated whenever the
391
         */
392
        if ("size" in file)
393
            total_file_size += file.size;
394
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
395
        tr = files_children[i];
396
        checked = tr.firstChild.firstChild.checked;
397
        /* Set the class for every row based on both the checked state,
398
         * and whether it is odd or even */
399
        tr.setAttribute("class", "row" + row_toggle.toString() +
400
            (checked ? "sel" : ""))
401
        row_toggle = row_toggle == 1 ? 2 : 1;
402
        if (checked)
403
        {
404
            /* Add the filename (column 3) to the selected_files list */
405
            selected_files[selected_files.length] = filename;
210 by mattgiuca
File browser: listing.js - The status bar is now updated whenever the
406
            if ("size" in file)
407
                total_file_size_sel += file.size;
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
408
        }
210 by mattgiuca
File browser: listing.js - The status bar is now updated whenever the
409
    }
410
597 by mattgiuca
Major refactor of actions in File browser.
411
    /* Write to the side-panel and actions bar */
412
    update_actions();
211 by mattgiuca
fileservice/listing: Slight change to date format.
413
    update_sidepanel(total_file_size_sel);
414
210 by mattgiuca
File browser: listing.js - The status bar is now updated whenever the
415
    /* Write to the status bar */
416
    var statusbar = document.getElementById("statusbar");
417
    var statusmsg;
418
    var file_plural;
419
    if (selected_files.length > 0)
420
    {
421
        statusmsg = selected_files.length.toString() + " file"
422
            + (selected_files.length == 1 ? "" : "s") + " selected, "
423
            + nice_filesize(total_file_size_sel);
424
    }
425
    else
426
    {
237 by mattgiuca
listing: bugfix, update_selection no longer dependent on dictionary ordering
427
        statusmsg = files_children.length.toString() + " file"
428
            + (files_children.length == 1 ? "" : "s") + ", "
210 by mattgiuca
File browser: listing.js - The status bar is now updated whenever the
429
            + nice_filesize(total_file_size);
430
    }
431
    dom_removechildren(statusbar);
432
    statusbar.appendChild(document.createTextNode(statusmsg));
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
433
}
434
235 by mattgiuca
listing.js: Added sorting functions and a bit of infrastructure to facilitate
435
/** SORTING FUNCTIONS **/
436
437
/** Sorts the file table. Physically manipulates the DOM table to reflect the
438
 * sorted nodes, and also updates the little sort arrow.
439
 *
440
 * \param sort_field The name of the field to sort on primarily. This can
441
 * either be "filename", or one of the fields of a fileinfo object. Note that
442
 * while this determines the primary sort key, the secondary sort keys are
443
 * determined by the global sort_order. Calling sort_listing reorders
444
 * sort_order, bringing the specified sort_field to the top.
445
 * Also note that sorting by "isdir" is more prominent than whatever field is
446
 * provided here.
240 by mattgiuca
browser/listing.js: Wrote real comparison function and set up sort_order array
447
 * \param ascending If true, sorts ascending. If false, descending.
235 by mattgiuca
listing.js: Added sorting functions and a bit of infrastructure to facilitate
448
 */
240 by mattgiuca
browser/listing.js: Wrote real comparison function and set up sort_order array
449
function sort_listing(sort_field, ascending)
235 by mattgiuca
listing.js: Added sorting functions and a bit of infrastructure to facilitate
450
{
451
    var i;
452
    var files = document.getElementById("files");
453
    var files_children = files.childNodes;
454
    var files_array = new Array(files_children.length);
455
    /* Update sort_order, bringing sort_field to the top. */
557 by agdimech
/browser/listing.js: Fixed ascending/descending functionality when clicked.
456
    if(sort_order[sort_order.length-1] == sort_field)
457
    {
458
        sort_ascending = ascending != false ? true : false;
459
    }
460
    else
461
    {
462
        sort_ascending = true;
463
        sort_order.removeall(sort_field);
464
        sort_order.push(sort_field);
465
    }
235 by mattgiuca
listing.js: Added sorting functions and a bit of infrastructure to facilitate
466
467
    /* Build an array of DOM tr elements (with the additional 'filename' and
468
     * 'fileinfo' attributes as written when the listing is created). */
469
    /* Note: Must manually create an array from files_children, which is a DOM
470
     * NodeList, not an array. */
471
    for (i=0; i<files_children.length; i++)
472
        files_array[i] = files_children[i];
473
474
    /* Sort this array */
475
    files_array.sort(compare_files);
476
477
    /* Clean out the table (the TRs are safely stored in the array) */
478
    dom_removechildren(files);
479
480
    /* Insert the TRs back into the table, in their sorted order */
481
    for (i=0; i<files_array.length; i++)
482
        files.appendChild(files_array[i]);
483
484
    /* Fix the coloring classes on the rows so they are interleaved. */
485
    update_selection();
486
487
    return false;
488
}
489
490
/** Comparison function used for sorting. Compares two DOM tr nodes (with
491
 * the additional 'filename' and 'fileinfo' attributes as written when the
492
 * listing is created).
493
 * Returns an integer, which is -1 if a < b, 0 if a == b, and 1 if a > b.
494
 * The fields to compare by are determined by the global variable sort_order.
495
 */
496
function compare_files(a, b)
497
{
236 by mattgiuca
listing.js: Correct sorting by directory. (Now sorts all directories to the
498
    /* First sort by whether or not it is a directory */
499
    var aisdir = a.fileinfo.isdir == true;
500
    var bisdir = b.fileinfo.isdir == true;
240 by mattgiuca
browser/listing.js: Wrote real comparison function and set up sort_order array
501
    var LESS = sort_ascending == true ? -1 : 1;
502
    var GREATER = -LESS;
503
    if (aisdir > bisdir) return LESS;
504
    else if (aisdir < bisdir) return GREATER;
235 by mattgiuca
listing.js: Added sorting functions and a bit of infrastructure to facilitate
505
240 by mattgiuca
browser/listing.js: Wrote real comparison function and set up sort_order array
506
    /* Reverse order of sort_order. (top is highest priority) */
507
    for (var i=sort_order.length-1; i>=0; i--)
508
    {
509
        var field = sort_order[i];
510
        if (field == "filename")
511
        {
512
            if (a.filename < b.filename) return LESS;
513
            else if (a.filename > b.filename) return GREATER;
514
        }
515
        else
516
        {
517
            /* null > anything else (so it appears at the bottom) */
543 by agdimech
browser/listing.js: Fixed sorting for date and size by adding .fileinfo
518
            if (!(field in a.fileinfo))
555 by agdimech
browser/listing.js: Fixed priority queue for sorting due to layout issues.
519
            {
520
                if (field in b.fileinfo)
521
                    return GREATER;
522
                else
523
                    break;
524
            }
543 by agdimech
browser/listing.js: Fixed sorting for date and size by adding .fileinfo
525
            if (!(field in b.fileinfo)) return LESS;
240 by mattgiuca
browser/listing.js: Wrote real comparison function and set up sort_order array
526
            if (a.fileinfo[field] < b.fileinfo[field]) return LESS;
527
            else if (a.fileinfo[field] > b.fileinfo[field]) return GREATER;
528
        }
529
    }
235 by mattgiuca
listing.js: Added sorting functions and a bit of infrastructure to facilitate
530
531
    return 0;
532
}
533
534
/** END SORTING **/
535
980 by dcoles
Files: "Junk" is now only shown when other (non-subject/stuff) files are in the
536
/** Initialises the DOM elements required to present files window,
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
537
 * assuming that clear_page has just been called or the page just
538
 * loaded for the first time.
539
 */
980 by dcoles
Files: "Junk" is now only shown when other (non-subject/stuff) files are in the
540
function setup_for_listing()
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
541
{
542
    var filesbody = document.getElementById("filesbody");
543
381 by mattgiuca
media/browser/listing.js: Replaced table-based layout in file listing with
544
    /* There are 2 divs in the filesbody: middle and statusbar
545
     * middle has 2 divs: filetable, sidepanel
546
     */
547
    /* Middle */
548
    var middle = document.createElement("div");
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
549
    filesbody.appendChild(middle);
550
    middle.setAttribute("id", "middle");
381 by mattgiuca
media/browser/listing.js: Replaced table-based layout in file listing with
551
    /* File table */
552
    var filetable = document.createElement("div");
553
    middle.appendChild(filetable);
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
554
    filetable.setAttribute("id", "filetable");
555
    var filetablediv = document.createElement("div");
556
    filetable.appendChild(filetablediv);
557
    filetablediv.setAttribute("id", "filetablediv");
980 by dcoles
Files: "Junk" is now only shown when other (non-subject/stuff) files are in the
558
559
    /* Side-panel */
560
    /* 2 nested divs, so we can set the width exactly and have padding inside
561
     * of that */
562
    var sidepanel_outer = document.createElement("div");
563
    middle.appendChild(sidepanel_outer);
564
    sidepanel_outer.setAttribute("id", "sidepanel_outer");
565
    var sidepanel = document.createElement("div");
566
    sidepanel_outer.appendChild(sidepanel);
567
    sidepanel.setAttribute("id", "sidepanel");
568
569
    /* Now after the table "middle", there is a status bar */
570
    var statusbar_outer = document.createElement("div");
571
    filesbody.appendChild(statusbar_outer);
572
    statusbar_outer.setAttribute("id", "statusbar_outer");
573
    var statusbar = document.createElement("div");
574
    statusbar_outer.appendChild(statusbar);
575
    statusbar.setAttribute("id", "statusbar");
576
}
577
578
/** Sets up the DOM elements required to present a directory liisting.
579
 */
580
function setup_dir_listing()
581
{
582
    var filesbody = document.getElementById("filesbody");
583
    var filetable = document.getElementById("filetable");
584
    var filetablediv = document.getElementById("filetablediv");
585
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
586
    /* A nested table within this div - the actual files listing */
587
    var filetabletable = document.createElement("table");
588
    filetablediv.appendChild(filetabletable);
589
    filetabletable.setAttribute("width", "100%");
590
    var filetablethead = document.createElement("thead");
591
    filetabletable.appendChild(filetablethead);
592
    var filetablethead_tr = document.createElement("tr");
593
    filetablethead.appendChild(filetablethead_tr);
594
    filetablethead_tr.setAttribute("class", "rowhead");
595
    /* Row headers */
596
    var filetablethead_th = document.createElement("th");
597
    filetablethead_tr.appendChild(filetablethead_th);
598
    filetablethead_th.setAttribute("class", "col-check");
599
    filetablethead_th = dom_make_link_elem("th", "Filename",
545 by agdimech
browser/listing.js: Fixed part of the ascending/descending sort however it doesnt take into account changes in primary key.
600
        "Sort by filename", null,
601
	"return sort_listing(\"filename\", !sort_ascending)");
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
602
    filetablethead_tr.appendChild(filetablethead_th);
603
    filetablethead_th.setAttribute("class", "col-filename");
604
    filetablethead_th.setAttribute("colspan", 3);
605
    filetablethead_th = dom_make_link_elem("th", "Size",
545 by agdimech
browser/listing.js: Fixed part of the ascending/descending sort however it doesnt take into account changes in primary key.
606
        "Sort by file size", null, "return sort_listing(\"size\",!sort_ascending)");
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
607
    filetablethead_tr.appendChild(filetablethead_th);
608
    filetablethead_th.setAttribute("class", "col-size");
609
    filetablethead_th = dom_make_link_elem("th", "Modified",
545 by agdimech
browser/listing.js: Fixed part of the ascending/descending sort however it doesnt take into account changes in primary key.
610
        "Sort by date modified", null, "return sort_listing(\"mtime\",!sort_ascending)");
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
611
    filetablethead_tr.appendChild(filetablethead_th);
612
    filetablethead_th.setAttribute("class", "col-date");
613
    /* Empty body */
614
    var filetabletbody = document.createElement("tbody");
615
    filetabletable.appendChild(filetabletbody);
616
    filetabletbody.setAttribute("id", "files");
617
}
618
619
/** Presents the directory listing.
620
 */
980 by dcoles
Files: "Junk" is now only shown when other (non-subject/stuff) files are in the
621
function handle_dir_listing(path, listing)
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
622
{
980 by dcoles
Files: "Junk" is now only shown when other (non-subject/stuff) files are in the
623
    /* Add the DOM elements for the file listing */
624
    setup_dir_listing()
625
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
626
    var row_toggle = 1;
980 by dcoles
Files: "Junk" is now only shown when other (non-subject/stuff) files are in the
627
    
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
628
    /* Is this dir under svn? */
944 by dcoles
Special Home Directory: Work to create a special home directory that shows the
629
    var under_subversion = ("svnstatus" in current_file) && (current_file.svnstatus != "unversioned");
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
630
631
    var files = document.getElementById("files");
632
    var file;
633
    var row;
634
    var td;
635
    var checkbox;
636
386 by mattgiuca
browser/listing: Fixed long-standing bug, files get deselected when you
637
    /* Convert selected_files array into a dictionary which can be efficiently
638
     * searched. */
639
    sel_files_dict = {};
640
    for (var i=0; i<selected_files.length; i++)
641
    {
642
        sel_files_dict[selected_files[i]] = true;
643
    }
644
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
645
    /* Create all of the files */
646
    for (var filename in listing)
647
    {
1060 by wagrant
Make IVLE work fine in Firefox 3.1 (ie. Gecko/XULRunner 1.9.1). Gecko 1.9.1 has
648
        select_row = function() {
649
            var files_children = document.getElementById("files").childNodes;
650
            var checkbox;
651
            var tr;
652
            for (var i=0; i<files_children.length; i++)
653
            {
654
                tr = files_children[i];
655
                checkbox = tr.firstChild.firstChild;
656
                checkbox.checked = tr == this.parentNode;
657
            }
658
            update_selection();
659
        }
660
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
661
        file = listing[filename];
234 by mattgiuca
browser/listing.js:
662
        /* Make a 'tr' element. Store the filename and fileinfo in
663
         * here. */
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
664
        row = document.createElement("tr");
234 by mattgiuca
browser/listing.js:
665
        row.filename = filename;
666
        row.fileinfo = file;
909 by wagrant
listing.js: Remove duplication in get_dir_listing's row generation.
667
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
668
        /* Column 1: Selection checkbox */
669
        row.setAttribute("class", "row" + row_toggle.toString())
670
        row_toggle = row_toggle == 1 ? 2 : 1;
671
        td = document.createElement("td");
672
        checkbox = document.createElement("input");
673
        checkbox.setAttribute("type", "checkbox");
674
        checkbox.setAttribute("title", "Select this file");
675
        checkbox.setAttribute("onchange", "update_selection()");
386 by mattgiuca
browser/listing: Fixed long-standing bug, files get deselected when you
676
        /* Check the box if selected_files says it's selected */
677
        checkbox.checked = filename in sel_files_dict;
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
678
        td.appendChild(checkbox);
679
        row.appendChild(td);
909 by wagrant
listing.js: Remove duplication in get_dir_listing's row generation.
680
681
        /* Column 2: Filetype and subversion icons. */
682
        td = document.createElement("td");
683
        td.setAttribute("class", "thincol");
1060 by wagrant
Make IVLE work fine in Firefox 3.1 (ie. Gecko/XULRunner 1.9.1). Gecko 1.9.1 has
684
        td.addEventListener("click", select_row, false);
909 by wagrant
listing.js: Remove duplication in get_dir_listing's row generation.
685
        /* Directories don't really have a MIME type, so we fake one. */
686
        if (file.isdir) file.type = "text/directory";
687
        td.appendChild(dom_make_img(mime_type_to_icon(file.type),
688
            icon_size, icon_size, file.type_nice));
689
        row.appendChild(td);
690
        td = document.createElement("td");
691
        td.setAttribute("class", "thincol");
692
        if (under_subversion)
693
        {
694
            var icon = svnstatus_to_icon(file.svnstatus);
695
            if (icon)
696
                td.appendChild(dom_make_img(icon, icon_size, icon_size,
697
                    svnstatus_to_string(file.svnstatus)));
698
        }
699
        row.appendChild(td);
700
701
        /* Column 3: Filename */
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
702
        if (file.isdir)
703
        {
704
            td = dom_make_link_elem("td", filename,
909 by wagrant
listing.js: Remove duplication in get_dir_listing's row generation.
705
                 "Navigate to " + path_join(path, filename),
910 by wagrant
filebrowser_lib: Send the current revision along with the listing if we
706
                 build_revision_url(path, filename, current_revision),
707
                 null, true);
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
708
        }
709
        else
710
        {
711
            td = dom_make_text_elem("td", filename);
712
        }
1060 by wagrant
Make IVLE work fine in Firefox 3.1 (ie. Gecko/XULRunner 1.9.1). Gecko 1.9.1 has
713
        td.addEventListener("click", select_row, false);
909 by wagrant
listing.js: Remove duplication in get_dir_listing's row generation.
714
        row.appendChild(td);
715
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
716
        /* Column 4: Size */
717
        td = dom_make_text_elem("td", nice_filesize(file.size));
1060 by wagrant
Make IVLE work fine in Firefox 3.1 (ie. Gecko/XULRunner 1.9.1). Gecko 1.9.1 has
718
        td.addEventListener("click", select_row, false);
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
719
        row.appendChild(td);
909 by wagrant
listing.js: Remove duplication in get_dir_listing's row generation.
720
721
        /* Column 5: Date */
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
722
        td = dom_make_text_elem("td", file.mtime_short, file.mtime_nice);
1060 by wagrant
Make IVLE work fine in Firefox 3.1 (ie. Gecko/XULRunner 1.9.1). Gecko 1.9.1 has
723
        td.addEventListener("click", select_row, false);
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
724
        row.appendChild(td);
725
        files.appendChild(row);
726
    }
727
237 by mattgiuca
listing: bugfix, update_selection no longer dependent on dictionary ordering
728
    /* Apply an initial sort by filename */
729
    sort_listing("filename");
730
210 by mattgiuca
File browser: listing.js - The status bar is now updated whenever the
731
    /* Do a selection update (create initial elements for side panel and
732
     * status bar). */
237 by mattgiuca
listing: bugfix, update_selection no longer dependent on dictionary ordering
733
    /* Commented out; already called by sort_listing */
734
    /*update_selection();*/
209 by mattgiuca
browser.js: Split out dir-listing code into listing.js (it's going to get
735
}
736