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

« back to all changes in this revision

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

  • Committer: wagrant
  • Date: 2008-07-17 02:04:16 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:901
svnlogservice: Fix arbitrary content injection by commit message.

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. */
 
705
    set_action_state(["svnadd", "svnrevert", "svncommit"], numsel >= 1 && current_file.svnstatus);
 
706
 
 
707
    /* Diff and log only support one path at the moment, so we must have 0 or 1
 
708
     * versioned files selected. If 0, the directory must be versioned. */
777
709
    single_versioned_path = (
778
710
         (
779
711
          (numsel == 1 && (svnst = file_listing[selected_files[0]].svnstatus)) ||
780
712
          (numsel == 0 && (svnst = current_file.svnstatus))
781
713
         ) && 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);
 
714
    set_action_state(["svnlog", "svndiff"], single_versioned_path);
 
715
 
 
716
    /* current_path == username: We are at the top level */
 
717
    set_action_state("svncheckout", current_path == username);
801
718
 
802
719
    /* There is currently nothing on the More Actions menu of use
803
720
     * when the current file is not a directory. Hence, just remove
810
727
    {
811
728
        var actions2_directory = document.getElementById("actions2_directory");
812
729
        actions2_directory.setAttribute("style", "display: inline;");
813
 
        var moreactions = document.getElementById("moreactions_area");
814
 
        moreactions.setAttribute("style", "display: inline;");
815
730
    }
816
731
    else
817
732
    {
818
733
        var actions2_file = document.getElementById("actions2_file");
819
734
        actions2_file.setAttribute("style", "display: inline;");
 
735
        var moreactions = document.getElementById("moreactions_area");
 
736
        moreactions.setAttribute("style", "display: none;");
820
737
    }
821
738
 
822
739
    return;
853
770
        action_unpublish(selected_files);
854
771
        break;
855
772
    case "share":
856
 
        window.open(public_app_path("~" + current_path, filename), 'share')
 
773
        //alert("Not yet implemented: Sharing files");
 
774
        window.open(public_app_path(serve_app, current_path, filename), 'share')
857
775
        break;
858
776
    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
 
 
 
777
        // TODO
 
778
        alert("Not yet implemented: Submit");
878
779
        break;
879
780
    case "rename":
880
781
        action_rename(filename);
881
782
        break;
882
783
    case "delete":
883
 
        action_delete(selected_files);
 
784
        action_remove(selected_files);
884
785
        break;
885
786
    case "copy":
886
787
        action_copy(selected_files);
903
804
    case "svnadd":
904
805
        action_add(selected_files);
905
806
        break;
906
 
    case "svnremove":
907
 
        action_remove(selected_files);
908
 
        break;
909
807
    case "svnrevert":
910
808
        action_revert(selected_files);
911
809
        break;
912
810
    case "svndiff":
913
811
        window.location = path_join(app_path('diff'), current_path, selected_files[0] || '');
914
812
        break;
915
 
    case "svnupdate":
916
 
        action_update(selected_files);
917
 
        break;
918
 
    case "svnresolved":
919
 
        action_resolved(selected_files);
920
 
        break;
921
813
    case "svncommit":
922
814
        action_commit(selected_files);
923
815
        break;
924
816
    case "svnlog":
925
817
        window.location = path_join(app_path('svnlog'), current_path, selected_files[0] || '');
926
818
        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(".");
 
819
    case "svncheckout":
 
820
        action_checkout();
935
821
        break;
936
822
    }
937
823
}
960
846
     * This causes the page to be populated with whatever is at that address,
961
847
     * whether it be a directory or a file.
962
848
     */
963
 
    var path = get_path();
964
 
    navigate(path);
965
 
}
966
 
 
967
 
/** Gets the current path of the window */
968
 
function get_path() {
969
849
    var path = parse_url(window.location.href).path;
970
850
    /* Strip out root_dir + "/files" from the front of the path */
971
851
    var strip = make_path(this_app);
988
868
        path = username;
989
869
    }
990
870
 
991
 
    return path;
 
871
    navigate(path);
992
872
}