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

« back to all changes in this revision

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

  • Committer: dcoles
  • Date: 2008-07-03 04:20:54 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:803
Setup: Modularised setup.py so it is now no longer over 1000 lines. This should 
allow us to get in there and tidy up each module much easier. Also removed 
updatejails since this functionality seems to be duplicated with remakeuser.py 
and remakealluser.py scripts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
default_type_icon = "txt.png";
56
56
 
57
57
/* Relative to IVLE root */
58
 
type_icons_path = "+media/ivle.webapp.core/images/mime";
59
 
type_icons_path_large = "+media/ivle.webapp.core/images/mime/large";
 
58
type_icons_path = "media/images/mime";
 
59
type_icons_path_large = "media/images/mime/large";
60
60
 
61
61
/* Mapping SVN status to icons, just the file's basename */
62
62
svn_icons = {
66
66
    "missing": "missing.png",
67
67
    "deleted": "deleted.png",
68
68
    "modified": "modified.png",
69
 
    "conflicted": "conflicted.png",
70
69
    "revision": "revision.png"
71
70
};
72
71
 
87
86
default_svn_icon = null;
88
87
default_svn_nice = "Unknown status";
89
88
 
90
 
svn_icons_path = "+media/ivle.webapp.core/images/svn";
 
89
svn_icons_path = "media/images/svn";
91
90
 
92
 
published_icon = "+media/ivle.webapp.core/images/interface/published.png";
 
91
published_icon = "media/images/interface/published.png";
93
92
 
94
93
/* List of MIME types considered "executable" by the system.
95
94
 * Executable files offer a "run" link, implying that the "serve"
105
104
/** The listing object returned by the server as JSON */
106
105
file_listing = null;
107
106
current_file = null;
108
 
current_revision = null;
109
107
current_path = "";
110
108
 
111
109
/** Filenames of all files selected
183
181
 */
184
182
function refresh()
185
183
{
186
 
    if (maybe_save('All changes since the last save will be lost!'))
187
 
        navigate(current_path);
 
184
    navigate(current_path);
188
185
}
189
186
 
190
187
/** Determines the "handler type" from a MIME type.
241
238
        return;
242
239
    }
243
240
 
244
 
    var subjects = null;
245
 
    var top_level_dir = path==username;
246
 
    if (top_level_dir)
247
 
    {
248
 
        var req = ajax_call(null, "userservice", "get_enrolments", null, "GET")
249
 
        subjects = decode_response(req);
250
 
    }
251
 
 
252
 
 
253
241
    /* This will always return a listing, whether it is a dir or a file.
254
242
     */
255
243
    var listing = response.responseText;
298
286
    current_file = file_listing["."];     /* Global */
299
287
    delete file_listing["."];
300
288
 
301
 
    if ('revision' in listing)
302
 
    {
303
 
        current_revision = listing.revision;
304
 
    }
305
 
 
306
289
    /* Check if this is a directory listing or file contents */
307
290
    var isdir = response.getResponseHeader("X-IVLE-Return") == "Dir";
308
291
    if (isdir)
309
292
    {
310
 
        setup_for_listing();
311
 
        home_listing(listing, subjects, path);
 
293
        handle_dir_listing(path, listing);
312
294
    }
313
295
    else
314
296
    {
376
358
     */
377
359
    upload_callback_count++;
378
360
    if (upload_callback_count >= 2)
379
 
    {
380
 
        myFrame = frames['upload_iframe'].document;
381
 
        data = myFrame.firstChild.childNodes[1].firstChild.firstChild.nodeValue;
382
 
        data = JSON.parse(data);
383
 
        if ('Error' in data)
384
 
            alert("Error: " + decodeURIComponent(data['Error']));
385
 
        document.getElementsByName('data')[0].value = '';
386
361
        refresh();
387
 
    }
388
362
}
389
363
 
390
364
/** Deletes all "dynamic" content on the page.
396
370
    dom_removechildren(document.getElementById("filesbody"));
397
371
}
398
372
 
399
 
/* Checks if a file needs to be saved. If it does, the user will be asked
400
 
 * if they want to continue anyway. The caller must specify a warning
401
 
 * sentence which indicates the consequences of continuing.
402
 
 * Returns true if we should continue, and false if we should not.
403
 
 */
404
 
function maybe_save(warning)
405
 
{
406
 
    if (warning == null) warning = '';
407
 
    if (current_file.isdir) return true;
408
 
    if (document.getElementById("save_button").disabled) return true;
409
 
    return confirm("This file has unsaved changes. " + warning +
410
 
                   "\nAre you sure you wish to continue?");
411
 
}
412
 
 
413
373
/** Deletes all "dynamic" content on the page necessary to navigate from
414
374
 * one directory listing to another (does not clear as much as clearpage
415
375
 * does).
449
409
    files.appendChild(txt_elem);
450
410
}
451
411
 
452
 
/** Given a path, filename and optional revision, returns a URL to open that
453
 
 *  revision of that file.
454
 
 */
455
 
function build_revision_url(path, filename, revision)
456
 
{
457
 
    bits = {'path': app_path(this_app, path, filename)};
458
 
    if (current_revision)
459
 
    {
460
 
        bits['query_string'] = 'r=' + revision;
461
 
    }
462
 
    return build_url(bits);
463
 
}
464
 
 
465
412
/** Given a mime type, returns the path to the icon.
466
413
 * \param type String, Mime type.
467
414
 * \param sizelarge Boolean, optional.
525
472
    div.appendChild(par2);
526
473
}
527
474
 
528
 
/* Enable or disable actions1 moreactions actions. Takes either a single
529
 
 * name, or an array of them.*/
530
 
function set_action_state(names, which, allow_on_revision)
531
 
{
532
 
    if (!(names instanceof Array)) names = Array(names);
533
 
 
534
 
    for (var i=0; i < names.length; i++)
535
 
    {
536
 
        element = document.getElementById('act_' + names[i]);
537
 
        if (which &&
538
 
            !(current_file.svnstatus == 'revision' && !allow_on_revision))
539
 
        {
540
 
            /* Enabling */
541
 
            element.setAttribute("class", "choice");
542
 
            element.removeAttribute("disabled");
543
 
        }
544
 
        else
545
 
        {
546
 
            /* Disabling */
547
 
            element.setAttribute("class", "disabled");
548
 
            element.setAttribute("disabled", "disabled");
549
 
        }
550
 
    }
551
 
}
552
 
 
553
 
/* Updates the list of available actions based on files selected */
554
475
function update_actions()
555
476
{
556
477
    var file;
557
478
    var numsel = selected_files.length;
558
 
    var svn_selection = false;
559
 
    
560
 
    if (numsel > 0)
561
 
    {
562
 
        svn_selection = true;
563
 
        for (var i = 0; i < selected_files.length; i++){
564
 
            if (file_listing[selected_files[i]]["svnstatus"] == "unversioned")
565
 
            {
566
 
                svn_selection = false;        
567
 
            }
568
 
        }
569
 
    }
570
 
    
571
479
    if (numsel <= 1)
572
480
    {
573
481
        if (numsel == 0)
599
507
        else
600
508
            open.setAttribute("title",
601
509
                "Edit or view this file");
602
 
        open.setAttribute("href", build_revision_url(current_path, filename,
603
 
                                                     current_revision));
 
510
        open.setAttribute("href", app_path(this_app, current_path, filename));
604
511
    }
605
512
    else
606
513
    {
613
520
    /* Available if zero or one files are selected,
614
521
     * and only if this is a file, not a directory */
615
522
    var serve = document.getElementById("act_serve");
616
 
    if (numsel <= 1 && !file.isdir && current_file.svnstatus != 'revision')
 
523
    if (numsel <= 1 && !file.isdir)
617
524
    {
618
525
        serve.setAttribute("class", "choice");
619
 
        serve.setAttribute("onclick",
620
 
              "return maybe_save('The last saved version will be served.')");
621
526
        if (numsel == 0)
622
527
            serve.setAttribute("href",
623
528
                app_path(serve_app, current_path));
629
534
    {
630
535
        serve.setAttribute("class", "disabled");
631
536
        serve.removeAttribute("href");
632
 
        serve.removeAttribute("onclick");
633
537
    }
634
538
 
635
539
    /* Run */
638
542
     */
639
543
    var run = document.getElementById("act_run");
640
544
     
641
 
    if (numsel <= 1 && !file.isdir && file.type == "text/x-python" 
642
 
            && current_file.svnstatus != 'revision')
643
 
    {
644
 
        if (numsel == 0)
645
 
        {
646
 
            // In the edit window
647
 
            var localpath = path_join('/home', current_path);
648
 
        }
649
 
        else
650
 
        {
651
 
            // In the browser window
652
 
            var localpath = path_join('/home', current_path, filename);
653
 
        }
654
 
        run.setAttribute("class", "choice");
 
545
    if (numsel == 0 && !file.isdir && file.type == "text/x-python")
 
546
    {
 
547
        // In the edit window
 
548
        run.setAttribute("class", "choice");
 
549
        localpath = app_path('home',current_path);
 
550
        run.setAttribute("onclick", "runfile('" + localpath + "')");
 
551
    }
 
552
    else if (numsel == 1 && !file.isdir && file.type == "text/x-python")
 
553
    {
 
554
        // In the browser window
 
555
        run.setAttribute("class", "choice");
 
556
        localpath = app_path('home',current_path,filename);
655
557
        run.setAttribute("onclick", "runfile('" + localpath + "')");
656
558
    }
657
559
    else
661
563
    }
662
564
 
663
565
    /* Download */
664
 
    /* Always available for current files.
 
566
    /* Always available.
665
567
     * If 0 files selected, download the current file or directory as a ZIP.
666
568
     * If 1 directory selected, download it as a ZIP.
667
569
     * If 1 non-directory selected, download it.
668
570
     * If >1 files selected, download them all as a ZIP.
669
571
     */
670
572
    var download = document.getElementById("act_download");
671
 
    if (current_file.svnstatus == 'revision')
672
 
    {
673
 
        download.setAttribute("class", "disabled");
674
 
        download.removeAttribute("onclick");
675
 
    }
676
 
    else if (numsel <= 1)
677
 
    {
678
 
        download.setAttribute("class", "choice")
 
573
    if (numsel <= 1)
 
574
    {
679
575
        if (numsel == 0)
680
576
        {
681
577
            download.setAttribute("href",
706
602
        for (var i=0; i<numsel; i++)
707
603
            dlpath += "path=" + encodeURIComponent(selected_files[i]) + "&";
708
604
        dlpath = dlpath.substr(0, dlpath.length-1);
709
 
        download.setAttribute("class", "choice")
710
605
        download.setAttribute("href", dlpath);
711
606
        download.setAttribute("title",
712
607
            "Download the selected files as a ZIP file");
719
614
     * directory. */
720
615
    var publish = document.getElementById("act_publish");
721
616
    var submit = document.getElementById("act_submit");
722
 
    var pubcond = numsel <= 1 && file.isdir;
723
 
    if (pubcond)
 
617
    if (numsel <= 1 && file.isdir)
724
618
    {
 
619
        /* TODO: Work out of file is svn'd */
 
620
        publish.setAttribute("class", "choice");
 
621
        publish.removeAttribute("disabled");
725
622
        /* If this dir is already published, call it "Unpublish" */
726
623
        if (file.published)
727
624
        {
735
632
                + "can be seen by anyone on the web");
736
633
            publish.textContent = "Publish";
737
634
        }
738
 
    }
739
 
    set_action_state(["publish", "submit"], pubcond);
 
635
        submit.setAttribute("class", "choice");
 
636
        submit.removeAttribute("disabled");
 
637
    }
 
638
    else
 
639
    {
 
640
        publish.setAttribute("class", "disabled");
 
641
        publish.setAttribute("disabled", "disabled");
 
642
        submit.setAttribute("class", "disabled");
 
643
        submit.setAttribute("disabled", "disabled");
 
644
    }
740
645
 
741
646
    /* Share */
742
 
    /* If exactly 1 non-directory file is selected, and its parent
 
647
    /* If exactly 1 non-directory file is selected/opened, and its parent
743
648
     * directory is published.
744
649
     */
745
 
    set_action_state("share", numsel == 1 && !file.isdir &&
746
 
                     current_file.published);
 
650
    var share = document.getElementById("act_share");
 
651
    if (numsel <= 1 && !file.isdir)
 
652
    {
 
653
        /* Work out if parent dir is published */
 
654
        parentdir = current_file;
 
655
        if (parentdir.published)
 
656
        {
 
657
            share.setAttribute("class", "choice");
 
658
            share.removeAttribute("disabled");
 
659
        } else {
 
660
            share.setAttribute("class", "disabled");
 
661
            share.setAttribute("disabled", "disabled");
 
662
        }
 
663
    }
 
664
    else
 
665
    {
 
666
        share.setAttribute("class", "disabled");
 
667
        share.setAttribute("disabled", "disabled");
 
668
    }
747
669
 
748
670
    /* Rename */
749
671
    /* If exactly 1 file is selected */
750
 
    set_action_state("rename", numsel == 1);
 
672
    var rename = document.getElementById("act_rename");
 
673
    if (numsel == 1)
 
674
    {
 
675
        rename.setAttribute("class", "choice");
 
676
        rename.removeAttribute("disabled");
 
677
    }
 
678
    else
 
679
    {
 
680
        rename.setAttribute("class", "disabled");
 
681
        rename.setAttribute("disabled", "disabled");
 
682
    }
751
683
 
752
684
    /* Delete, cut, copy */
753
685
    /* If >= 1 file is selected */
754
 
    set_action_state(["delete", "cut", "copy"], numsel >= 1);
 
686
    var act_delete = document.getElementById("act_delete");
 
687
    var cut = document.getElementById("act_cut");
 
688
    var copy = document.getElementById("act_copy");
 
689
    if (numsel >= 1)
 
690
    {
 
691
        act_delete.setAttribute("class", "choice");
 
692
        act_delete.removeAttribute("disabled");
 
693
        cut.setAttribute("class", "choice");
 
694
        cut.removeAttribute("disabled");
 
695
        copy.setAttribute("class", "choice");
 
696
        copy.removeAttribute("disabled");
 
697
    }
 
698
    else
 
699
    {
 
700
        act_delete.setAttribute("class", "disabled");
 
701
        act_delete.setAttribute("disabled", "disabled");
 
702
        cut.setAttribute("class", "disabled");
 
703
        cut.setAttribute("disabled", "disabled");
 
704
        copy.setAttribute("class", "disabled");
 
705
        copy.setAttribute("disabled", "disabled");
 
706
    }
755
707
 
756
708
    /* Paste, new file, new directory, upload */
757
709
    /* Disable if the current file is not a directory */
758
 
    set_action_state(["paste", "newfile", "mkdir", "upload"], current_file.isdir);
 
710
    if (!current_file.isdir)
 
711
    {
 
712
        var paste = document.getElementById("act_paste");
 
713
        var newfile = document.getElementById("act_newfile");
 
714
        var mkdir = document.getElementById("act_mkdir");
 
715
        var upload = document.getElementById("act_upload");
 
716
        paste.setAttribute("class", "disabled");
 
717
        paste.setAttribute("disabled", "disabled");
 
718
        newfile.setAttribute("class", "disabled");
 
719
        newfile.setAttribute("disabled", "disabled");
 
720
        mkdir.setAttribute("class", "disabled");
 
721
        mkdir.setAttribute("disabled", "disabled");
 
722
        upload.setAttribute("class", "disabled");
 
723
        upload.setAttribute("disabled", "disabled");
 
724
    }
759
725
 
760
726
    /* Subversion actions */
761
 
    /* These are only useful if we are in a versioned directory and have some
762
 
     * files selected. */
763
 
    set_action_state(["svnadd",], numsel >= 1 && current_file.svnstatus);
764
 
    /* And these are only usefull is ALL the selected files are versioned */
765
 
    set_action_state(["svnremove", "svnrevert", "svncommit", "svncopy", 
766
 
            "svncut"], numsel >= 1 && current_file.svnstatus && svn_selection);
767
 
    
768
 
    /* Diff, log and update only support one path at the moment, so we must
769
 
     * have 0 or 1 versioned files selected. If 0, the directory must be
770
 
     * versioned. */
771
 
    single_versioned_path = (
772
 
         (
773
 
          (numsel == 1 && (svnst = file_listing[selected_files[0]].svnstatus)) ||
774
 
          (numsel == 0 && (svnst = current_file.svnstatus))
775
 
         ) && svnst != "unversioned");
776
 
    set_action_state(["svndiff", "svnupdate"], single_versioned_path);
777
 
 
778
 
    /* We can resolve if we have a file selected and it is conflicted. */
779
 
    set_action_state("svnresolved", single_versioned_path && numsel == 1 && svnst == "conflicted");
780
 
 
781
 
    /* Log should be available for revisions as well. */
782
 
    set_action_state("svnlog", single_versioned_path, true);
 
727
    /* TODO: Work out when these are appropriate */
 
728
    var svnadd = document.getElementById("act_svnadd");
 
729
    var svnrevert = document.getElementById("act_svnrevert");
 
730
    var svncommit = document.getElementById("act_svncommit");
 
731
    if (true)
 
732
    {
 
733
        svnadd.setAttribute("class", "choice");
 
734
        svnadd.removeAttribute("disabled");
 
735
        svnrevert.setAttribute("class", "choice");
 
736
        svnrevert.removeAttribute("disabled");
 
737
        svncommit.setAttribute("class", "choice");
 
738
        svncommit.removeAttribute("disabled");
 
739
    }
 
740
    var svncheckout = document.getElementById("act_svncheckout");
 
741
    /* current_path == username: We are at the top level */
 
742
    if (current_path == username)
 
743
    {
 
744
        svncheckout.setAttribute("class", "choice");
 
745
        svncheckout.removeAttribute("disabled");
 
746
    }
 
747
    else
 
748
    {
 
749
        svncheckout.setAttribute("class", "disabled");
 
750
        svncheckout.setAttribute("disabled", "disabled");
 
751
    }
783
752
 
784
753
    /* There is currently nothing on the More Actions menu of use
785
754
     * when the current file is not a directory. Hence, just remove
786
755
     * it entirely.
787
756
     * (This makes some of the above decisions somewhat redundant).
788
 
     * We also take this opportunity to show the appropriate actions2
789
 
     * bar for this path. It should either be a save or upload widget.
790
757
     */
791
 
    if (current_file.isdir)
 
758
    if (!(current_file.isdir))
792
759
    {
793
 
        var actions2_directory = document.getElementById("actions2_directory");
794
 
        actions2_directory.setAttribute("style", "display: inline;");
795
760
        var moreactions = document.getElementById("moreactions_area");
796
 
        moreactions.setAttribute("style", "display: inline;");
797
 
    }
798
 
    else
799
 
    {
800
 
        var actions2_file = document.getElementById("actions2_file");
801
 
        actions2_file.setAttribute("style", "display: inline;");
 
761
        moreactions.setAttribute("style", "display: none;");
802
762
    }
803
763
 
804
764
    return;
835
795
        action_unpublish(selected_files);
836
796
        break;
837
797
    case "share":
838
 
        window.open(public_app_path("~" + current_path, filename), 'share')
 
798
        //alert("Not yet implemented: Sharing files");
 
799
        window.open(public_app_path(serve_app, current_path, filename), 'share')
839
800
        break;
840
801
    case "submit":
841
802
        // TODO
845
806
        action_rename(filename);
846
807
        break;
847
808
    case "delete":
848
 
        action_delete(selected_files);
 
809
        action_remove(selected_files);
849
810
        break;
850
811
    case "copy":
851
812
        action_copy(selected_files);
868
829
    case "svnadd":
869
830
        action_add(selected_files);
870
831
        break;
871
 
    case "svnremove":
872
 
        action_remove(selected_files);
873
 
        break;
874
832
    case "svnrevert":
875
833
        action_revert(selected_files);
876
834
        break;
877
 
    case "svndiff":
878
 
        window.location = path_join(app_path('diff'), current_path, selected_files[0] || '');
879
 
        break;
880
 
    case "svnupdate":
881
 
        action_update(selected_files);
882
 
        break;
883
 
    case "svnresolved":
884
 
        action_resolved(selected_files);
885
 
        break;
886
835
    case "svncommit":
887
836
        action_commit(selected_files);
888
837
        break;
889
 
    case "svnlog":
890
 
        window.location = path_join(app_path('svnlog'), current_path, selected_files[0] || '');
891
 
        break;
892
 
    case "svncopy":
893
 
        action_svncopy(selected_files);
894
 
        break;
895
 
    case "svncut":
896
 
        action_svncut(selected_files);
 
838
    case "svncheckout":
 
839
        action_checkout();
897
840
        break;
898
841
    }
899
842
}
903
846
 */
904
847
function runfile(localpath)
905
848
{
906
 
    if (!maybe_save('The last saved version will be run.')) return false;
907
 
 
908
849
    /* Dump the entire file to the console */
909
850
    var callback = function()
910
851
    {
916
857
 
917
858
/** Called when the page loads initially.
918
859
 */
919
 
function browser_init()
 
860
window.onload = function()
920
861
{
921
862
    /* Navigate (internally) to the path in the URL bar.
922
863
     * This causes the page to be populated with whatever is at that address,
945
886
    }
946
887
 
947
888
    navigate(path);
 
889
 
 
890
    /* Set up the console plugin to display as a popup window */
 
891
    console_init(true);
948
892
}