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

« back to all changes in this revision

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

  • Committer: mattgiuca
  • Date: 2008-07-15 07:19:34 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:875
Added "migrations" directory, which contains incremental database update
    scripts.
Updated users.sql, uniqueness key on offering table.
Added migration matching this update to the migrations directory. Mm handy!

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 = {
63
 
    "unversioned": "unversioned.png",
 
63
    "unversioned": null,
64
64
    "normal": "normal.png",
65
65
    "added": "added.png",
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
134
132
 *      May be "application/x-www-form-urlencoded" or "multipart/form-data".
135
133
 *      Defaults to "application/x-www-form-urlencoded".
136
134
 *      "multipart/form-data" is recommended for large uploads.
137
 
 * \param callback, optional.
138
 
 *      A callback function for after the action has been handled.
139
135
 */
140
 
function do_action(action, path, args, content_type, callback)
 
136
function do_action(action, path, args, content_type, ignore_response)
141
137
{
142
138
    args.action = action;
143
139
    /* Callback action, when the server returns */
144
 
    var callback_inner = function(response)
 
140
    var callback = function(response)
145
141
        {
146
142
            /* Check for action errors reported by the server, and report them
147
143
             * to the user */
148
144
            var error = response.getResponseHeader("X-IVLE-Action-Error");
149
 
            if (error != null && error != "")
 
145
            if (error != null)
150
146
                /* Note: This header (in particular) comes URI-encoded, to
151
147
                 * allow multi-line error messages. Decode */
152
148
                alert("Error: " + decodeURIComponent(error.toString()) + ".");
153
149
            /* Now read the response and set up the page accordingly */
154
 
            if (callback != null)
155
 
                callback(path, response);
 
150
            if (ignore_response != true)
 
151
                handle_response(path, response, true);
156
152
        }
157
153
    /* Call the server and perform the action. This mutates the server. */
158
 
    ajax_call(callback_inner, service_app, path, args, "POST", content_type);
 
154
    ajax_call(callback, service_app, path, args, "POST", content_type);
159
155
}
160
156
 
161
157
/** Calls the server using Ajax, requesting a directory listing. This should
243
239
        return;
244
240
    }
245
241
 
246
 
    var subjects = null;
247
 
    var top_level_dir = path==username;
248
 
    if (top_level_dir)
249
 
    {
250
 
        var req = ajax_call(null, "userservice", "get_enrolments", null, "GET")
251
 
        subjects = decode_response(req);
252
 
    }
253
 
 
254
 
 
255
242
    /* This will always return a listing, whether it is a dir or a file.
256
243
     */
257
244
    var listing = response.responseText;
300
287
    current_file = file_listing["."];     /* Global */
301
288
    delete file_listing["."];
302
289
 
303
 
    if ('revision' in listing)
304
 
    {
305
 
        current_revision = listing.revision;
306
 
    }
307
 
 
308
290
    /* Check if this is a directory listing or file contents */
309
291
    var isdir = response.getResponseHeader("X-IVLE-Return") == "Dir";
310
292
    if (isdir)
311
293
    {
312
 
        setup_for_listing();
313
 
        home_listing(listing, subjects, path);
 
294
        handle_dir_listing(path, listing);
314
295
    }
315
296
    else
316
297
    {
379
360
    upload_callback_count++;
380
361
    if (upload_callback_count >= 2)
381
362
    {
382
 
        myFrame = frames['upload_iframe'].document;
383
 
        /* Browsers will turn the raw returned JSON into an HTML document. We
384
 
         * need to get the <pre> from inside the <body>, and look at its text.
385
 
         */
386
 
        data = myFrame.firstChild.getElementsByTagName(
387
 
            'body')[0].firstChild.firstChild.nodeValue;
388
 
        data = JSON.parse(data);
389
 
        if ('Error' in data)
390
 
            alert("Error: " + decodeURIComponent(data['Error']));
391
363
        document.getElementsByName('data')[0].value = '';
392
364
        refresh();
393
365
    }
455
427
    files.appendChild(txt_elem);
456
428
}
457
429
 
458
 
/** Given a path, filename and optional revision, returns a URL to open that
459
 
 *  revision of that file.
460
 
 */
461
 
function build_revision_url(path, filename, revision)
462
 
{
463
 
    bits = {'path': app_path(this_app, path, filename)};
464
 
    if (current_revision)
465
 
    {
466
 
        bits['query_string'] = 'r=' + revision;
467
 
    }
468
 
    return build_url(bits);
469
 
}
470
 
 
471
430
/** Given a mime type, returns the path to the icon.
472
431
 * \param type String, Mime type.
473
432
 * \param sizelarge Boolean, optional.
533
492
 
534
493
/* Enable or disable actions1 moreactions actions. Takes either a single
535
494
 * name, or an array of them.*/
536
 
function set_action_state(names, which, allow_on_revision)
 
495
function set_action_state(names, which)
537
496
{
538
497
    if (!(names instanceof Array)) names = Array(names);
539
498
 
540
499
    for (var i=0; i < names.length; i++)
541
500
    {
542
501
        element = document.getElementById('act_' + names[i]);
543
 
        if (which &&
544
 
            !(current_file.svnstatus == 'revision' && !allow_on_revision))
 
502
        if (which)
545
503
        {
546
504
            /* Enabling */
547
505
            element.setAttribute("class", "choice");
556
514
    }
557
515
}
558
516
 
559
 
/* Updates the list of available actions based on files selected */
560
517
function update_actions()
561
518
{
562
519
    var file;
563
520
    var numsel = selected_files.length;
564
 
    var svn_selection = false;
565
 
    
566
 
    if (numsel > 0)
567
 
    {
568
 
        svn_selection = true;
569
 
        for (var i = 0; i < selected_files.length; i++){
570
 
            if (file_listing[selected_files[i]]["svnstatus"] == "unversioned")
571
 
            {
572
 
                svn_selection = false;        
573
 
            }
574
 
        }
575
 
    }
576
 
    
577
521
    if (numsel <= 1)
578
522
    {
579
523
        if (numsel == 0)
605
549
        else
606
550
            open.setAttribute("title",
607
551
                "Edit or view this file");
608
 
        open.setAttribute("href", build_revision_url(current_path, filename,
609
 
                                                     current_revision));
 
552
        open.setAttribute("href", app_path(this_app, current_path, filename));
610
553
    }
611
554
    else
612
555
    {
619
562
    /* Available if zero or one files are selected,
620
563
     * and only if this is a file, not a directory */
621
564
    var serve = document.getElementById("act_serve");
622
 
    if (numsel <= 1 && !file.isdir && current_file.svnstatus != 'revision')
 
565
    if (numsel <= 1 && !file.isdir)
623
566
    {
624
567
        serve.setAttribute("class", "choice");
625
568
        serve.setAttribute("onclick",
644
587
     */
645
588
    var run = document.getElementById("act_run");
646
589
     
647
 
    if (numsel <= 1 && !file.isdir && file.type == "text/x-python" 
648
 
            && current_file.svnstatus != 'revision')
 
590
    if (!file.isdir && file.type == "text/x-python" && numsel <= 1)
649
591
    {
650
592
        if (numsel == 0)
651
593
        {
667
609
    }
668
610
 
669
611
    /* Download */
670
 
    /* Always available for current files.
 
612
    /* Always available.
671
613
     * If 0 files selected, download the current file or directory as a ZIP.
672
614
     * If 1 directory selected, download it as a ZIP.
673
615
     * If 1 non-directory selected, download it.
674
616
     * If >1 files selected, download them all as a ZIP.
675
617
     */
676
618
    var download = document.getElementById("act_download");
677
 
    if (current_file.svnstatus == 'revision')
678
 
    {
679
 
        download.setAttribute("class", "disabled");
680
 
        download.removeAttribute("onclick");
681
 
    }
682
 
    else if (numsel <= 1)
683
 
    {
684
 
        download.setAttribute("class", "choice")
 
619
    if (numsel <= 1)
 
620
    {
685
621
        if (numsel == 0)
686
622
        {
687
623
            download.setAttribute("href",
712
648
        for (var i=0; i<numsel; i++)
713
649
            dlpath += "path=" + encodeURIComponent(selected_files[i]) + "&";
714
650
        dlpath = dlpath.substr(0, dlpath.length-1);
715
 
        download.setAttribute("class", "choice")
716
651
        download.setAttribute("href", dlpath);
717
652
        download.setAttribute("title",
718
653
            "Download the selected files as a ZIP file");
728
663
    var pubcond = numsel <= 1 && file.isdir;
729
664
    if (pubcond)
730
665
    {
 
666
        /* TODO: Work out of file is svn'd */
731
667
        /* If this dir is already published, call it "Unpublish" */
732
668
        if (file.published)
733
669
        {
734
670
            publish.setAttribute("value", "unpublish");
735
671
            publish.setAttribute("title" ,"Make it so this directory "
736
672
                + "can not be seen by anyone on the web");
737
 
            publish.firstChild.nodeValue = "Unpublish";
 
673
            publish.textContent = "Unpublish";
738
674
        } else {
739
675
            publish.setAttribute("value", "publish");
740
676
            publish.setAttribute("title","Make it so this directory "
741
677
                + "can be seen by anyone on the web");
742
 
            publish.firstChild.nodeValue = "Publish";
 
678
            publish.textContent = "Publish";
743
679
        }
744
680
    }
745
681
    set_action_state(["publish", "submit"], pubcond);
766
702
    /* Subversion actions */
767
703
    /* These are only useful if we are in a versioned directory and have some
768
704
     * files selected. */
769
 
    set_action_state(["svnadd"], numsel >= 1 && current_file.svnstatus);
770
 
    /* And these are only usefull is ALL the selected files are versioned */
771
 
    set_action_state(["svnremove", "svnrevert", "svncommit", "svncopy", 
772
 
            "svncut"], numsel >= 1 && current_file.svnstatus && svn_selection);
773
 
    
774
 
    /* Diff, log and update only support one path at the moment, so we must
775
 
     * have 0 or 1 versioned files selected. If 0, the directory must be
776
 
     * versioned. */
777
 
    single_versioned_path = (
778
 
         (
779
 
          (numsel == 1 && (svnst = file_listing[selected_files[0]].svnstatus)) ||
780
 
          (numsel == 0 && (svnst = current_file.svnstatus))
781
 
         ) && svnst != "unversioned");
782
 
    set_action_state(["svndiff", "svnupdate"], single_versioned_path);
783
 
 
784
 
    /* We can resolve if we have a file selected and it is conflicted. */
785
 
    set_action_state("svnresolved", single_versioned_path && numsel == 1 && svnst == "conflicted");
786
 
 
787
 
    /* Log should be available for revisions as well. */
788
 
    set_action_state("svnlog", single_versioned_path, true);
789
 
 
790
 
    /* Cleanup should be available for revisions as well. */
791
 
    set_action_state("svncleanup", single_versioned_path, true);
792
 
 
793
 
    single_ivle_versioned_path = (
794
 
         (
795
 
          (numsel == 1 && (stat = file_listing[selected_files[0]])) ||
796
 
          (numsel == 0 && (stat = current_file))
797
 
         ) && stat.svnstatus != "unversioned"
798
 
           && stat.svnurl
799
 
           && stat.svnurl.substr(0, svn_base.length) == svn_base);
800
 
    set_action_state(["submit"], single_ivle_versioned_path);
 
705
    set_action_state(["svnadd", "svnrevert", "svncommit"], numsel >= 1 && current_file.svnstatus);
 
706
 
 
707
    /* Diff and log only support one path at the moment. */
 
708
    single_versioned_path = (numsel == 1 &&
 
709
                             (svnst = file_listing[selected_files[0]].svnstatus) &&
 
710
                             svnst != "unversioned");
 
711
    set_action_state("svnlog", single_versioned_path);
 
712
    set_action_state("svndiff", single_versioned_path && svnst != "normal");
 
713
 
 
714
    /* current_path == username: We are at the top level */
 
715
    set_action_state("svncheckout", current_path == username);
801
716
 
802
717
    /* There is currently nothing on the More Actions menu of use
803
718
     * when the current file is not a directory. Hence, just remove
810
725
    {
811
726
        var actions2_directory = document.getElementById("actions2_directory");
812
727
        actions2_directory.setAttribute("style", "display: inline;");
813
 
        var moreactions = document.getElementById("moreactions_area");
814
 
        moreactions.setAttribute("style", "display: inline;");
815
728
    }
816
729
    else
817
730
    {
818
731
        var actions2_file = document.getElementById("actions2_file");
819
732
        actions2_file.setAttribute("style", "display: inline;");
 
733
        var moreactions = document.getElementById("moreactions_area");
 
734
        moreactions.setAttribute("style", "display: none;");
820
735
    }
821
736
 
822
737
    return;
853
768
        action_unpublish(selected_files);
854
769
        break;
855
770
    case "share":
856
 
        window.open(public_app_path("~" + current_path, filename), 'share')
 
771
        //alert("Not yet implemented: Sharing files");
 
772
        window.open(public_app_path(serve_app, current_path, filename), 'share')
857
773
        break;
858
774
    case "submit":
859
 
        if (selected_files.length == 1)
860
 
            stat = file_listing[selected_files[0]];
861
 
        else
862
 
            stat = current_file;
863
 
        path = stat.svnurl.substr(svn_base.length);
864
 
 
865
 
        /* The working copy might not have an up-to-date version of the
866
 
         * directory. While submitting like this could yield unexpected
867
 
         * results, we should really submit the latest revision to minimise
868
 
         * terrible mistakes - so we run off and ask fileservice for the
869
 
         * latest revision.*/
870
 
        $.post(app_path(service_app, current_path),
871
 
            {"action": "svnrepostat", "path": path},
872
 
            function(result)
873
 
            {
874
 
                window.location = path_join(app_path('+submit'), path) + '?revision=' + result.svnrevision;
875
 
            },
876
 
            "json");
877
 
 
 
775
        // TODO
 
776
        alert("Not yet implemented: Submit");
878
777
        break;
879
778
    case "rename":
880
779
        action_rename(filename);
881
780
        break;
882
781
    case "delete":
883
 
        action_delete(selected_files);
 
782
        action_remove(selected_files);
884
783
        break;
885
784
    case "copy":
886
785
        action_copy(selected_files);
903
802
    case "svnadd":
904
803
        action_add(selected_files);
905
804
        break;
906
 
    case "svnremove":
907
 
        action_remove(selected_files);
908
 
        break;
909
805
    case "svnrevert":
910
806
        action_revert(selected_files);
911
807
        break;
912
808
    case "svndiff":
913
 
        window.location = path_join(app_path('diff'), current_path, selected_files[0] || '');
914
 
        break;
915
 
    case "svnupdate":
916
 
        action_update(selected_files);
917
 
        break;
918
 
    case "svnresolved":
919
 
        action_resolved(selected_files);
 
809
        window.location = path_join(app_path('diff'), current_path, selected_files[0]);
920
810
        break;
921
811
    case "svncommit":
922
812
        action_commit(selected_files);
923
813
        break;
924
814
    case "svnlog":
925
 
        window.location = path_join(app_path('svnlog'), current_path, selected_files[0] || '');
926
 
        break;
927
 
    case "svncopy":
928
 
        action_svncopy(selected_files);
929
 
        break;
930
 
    case "svncut":
931
 
        action_svncut(selected_files);
932
 
        break;
933
 
    case "svncleanup":
934
 
        action_svncleanup(".");
 
815
        window.location = path_join(app_path('svnlog'), current_path, selected_files[0]);
 
816
        break;
 
817
    case "svncheckout":
 
818
        action_checkout();
935
819
        break;
936
820
    }
937
821
}
960
844
     * This causes the page to be populated with whatever is at that address,
961
845
     * whether it be a directory or a file.
962
846
     */
963
 
    var path = get_path();
964
 
    navigate(path);
965
 
}
966
 
 
967
 
/** Gets the current path of the window */
968
 
function get_path() {
969
847
    var path = parse_url(window.location.href).path;
970
848
    /* Strip out root_dir + "/files" from the front of the path */
971
849
    var strip = make_path(this_app);
988
866
        path = username;
989
867
    }
990
868
 
991
 
    return path;
 
869
    navigate(path);
992
870
}