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

170 by mattgiuca
browser: Added CSS and JS files (not much in them).
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: File Browser (client)
19
 * Author: Matt Giuca
20
 * Date: 11/1/2008
21
 */
22
188 by mattgiuca
browser.js: Can now (shakily) handle directory listings. (lots of code!)
23
/* Url names for apps */
1339 by William Grant
Revert client-side parts of r1333; reliance on the deprecated tab mechanism is to be avoided.
24
this_app = "files";
208 by mattgiuca
dispatch.html, ivle.css: "apptabs" is now an ID, not a class.
25
edit_app = "edit";
188 by mattgiuca
browser.js: Can now (shakily) handle directory listings. (lots of code!)
26
service_app = "fileservice";
205 by mattgiuca
browser.js: Added appropriate handlers for error, text, and binary data.
27
serve_app = "serve";
28
download_app = "download";
188 by mattgiuca
browser.js: Can now (shakily) handle directory listings. (lots of code!)
29
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
30
/* Mapping MIME types onto handlers.
31
 * "text" : When navigating to a text file, the text editor is opened.
32
 * "image" : When navigating to an image, the image is displayed (rather than
33
 *              going to the text editor).
1791.2.1 by David Coles
File Browser: File handlers for Image, Audio and Video.
34
 * "video" : When navigation to a video file, a "play" button is presented.
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
35
 * "audio" : When navigating to an audio file, a "play" button is presented.
36
 * "binary" : When navigating to a binary file, offer it as a download through
37
 *              "serve".
38
 *
39
 * If a file is not on the list, its default action is determined by the first
40
 * part of its content type, where "text/*", "image/*" and "audio/*" are
41
 * treated as above, and other types are simply treated as binary.
42
 */
43
type_handlers = {
44
    "application/x-javascript" : "text",
45
    "application/javascript" : "text",
46
    "application/json" : "text",
1791.2.1 by David Coles
File Browser: File handlers for Image, Audio and Video.
47
    "application/xml" : "text",
1791.2.8 by David Coles
Add generic <object> media handler for suporting other media types (such as SVG)
48
    "application/ogg" : "audio",
49
    "image/svg+xml": "object"
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
50
};
51
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
52
/* Mapping MIME types to icons, just the file's basename */
53
type_icons = {
54
    "text/directory": "dir.png",
489 by agdimech
browser.js, editor.js: Fixed the syntax error which was resulting due to a trailing comma.
55
    "text/x-python": "py.png"
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
56
};
57
58
default_type_icon = "txt.png";
59
60
/* Relative to IVLE root */
1099.1.68 by William Grant
Move the remaining images to the new framework, in the new ivle.webapp.core
61
type_icons_path = "+media/ivle.webapp.core/images/mime";
62
type_icons_path_large = "+media/ivle.webapp.core/images/mime/large";
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
63
64
/* Mapping SVN status to icons, just the file's basename */
65
svn_icons = {
1449 by William Grant
Hook in the unversioned icon.
66
    "unversioned": "unversioned.png",
1663 by Matt Giuca
Added handlers and documentation for Subversion status 'ignored' (we call them 'Temporary file (ignored)'. This was previously handled as an 'unknown status'. Ignored files now can't have svn actions done on them either. This fixes Launchpad bug #526220.
67
    "ignored": null,                    /* Supposed to be innocuous */
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
68
    "normal": "normal.png",
213 by mattgiuca
Fileservice / Files (Python and JS files):
69
    "added": "added.png",
70
    "missing": "missing.png",
71
    "deleted": "deleted.png",
1653 by Matt Giuca
Added new Subversion status icon 'replaced', edited myself using Gimp from FamFamFam's added and deleted icons (previously showed nothing if this rare status ever showed up).
72
    "replaced": "replaced.png",
578 by dcoles
fileservice: Added code to allow browing of past revisons in the File Browser
73
    "modified": "modified.png",
918 by wagrant
browser: Expose svn update functionality. This brings a need for an
74
    "conflicted": "conflicted.png",
578 by dcoles
fileservice: Added code to allow browing of past revisons in the File Browser
75
    "revision": "revision.png"
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
76
};
77
213 by mattgiuca
Fileservice / Files (Python and JS files):
78
/* Mapping SVN status to "nice" strings */
79
svn_nice = {
80
    "unversioned": "Temporary file",
1663 by Matt Giuca
Added handlers and documentation for Subversion status 'ignored' (we call them 'Temporary file (ignored)'. This was previously handled as an 'unknown status'. Ignored files now can't have svn actions done on them either. This fixes Launchpad bug #526220.
81
    "ignored": "Temporary file (ignored)",
213 by mattgiuca
Fileservice / Files (Python and JS files):
82
    "normal": "Permanent file",
83
    "added": "Temporary file (scheduled to be added)",
84
    "missing": "Permanent file (missing)",
85
    "deleted": "Permanent file (scheduled for deletion)",
86
    "replaced": "Permanent file (replaced)",
87
    "modified": "Permanent file (modified)",
88
    "merged": "Permanent file (merged)",
578 by dcoles
fileservice: Added code to allow browing of past revisons in the File Browser
89
    "conflicted": "Permanent file (conflicted)",
90
    "revision": "Past Permanent file (revision)"
213 by mattgiuca
Fileservice / Files (Python and JS files):
91
};
92
230 by mattgiuca
Removed "unversioned" icon from subversion status. Now unversioned files do
93
default_svn_icon = null;
213 by mattgiuca
Fileservice / Files (Python and JS files):
94
default_svn_nice = "Unknown status";
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
95
1099.1.68 by William Grant
Move the remaining images to the new framework, in the new ivle.webapp.core
96
svn_icons_path = "+media/ivle.webapp.core/images/svn";
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
97
1099.1.68 by William Grant
Move the remaining images to the new framework, in the new ivle.webapp.core
98
published_icon = "+media/ivle.webapp.core/images/interface/published.png";
269 by mattgiuca
browser: Added publish functionality to JavaScript client side.
99
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
100
/* List of MIME types considered "executable" by the system.
101
 * Executable files offer a "run" link, implying that the "serve"
102
 * application can interpret them.
103
 */
104
types_exec = [
489 by agdimech
browser.js, editor.js: Fixed the syntax error which was resulting due to a trailing comma.
105
    "text/x-python"
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
106
];
107
211 by mattgiuca
fileservice/listing: Slight change to date format.
108
109
/* Global variables */
110
602 by mattgiuca
util.js: Added shallow_copy_object function.
111
/** The listing object returned by the server as JSON */
112
file_listing = null;
113
current_file = null;
910 by wagrant
filebrowser_lib: Send the current revision along with the listing if we
114
current_revision = null;
211 by mattgiuca
fileservice/listing: Slight change to date format.
115
current_path = "";
116
597 by mattgiuca
Major refactor of actions in File browser.
117
/** Filenames of all files selected
118
 * (Only used by dir listings, but still needs to be [] for files, so that
119
 * update_actions knows that nothing is selected).
120
 */
121
selected_files = [];
122
622 by mattgiuca
browser.js: Reinstated upload_callback (previously removed from listing.js).
123
upload_callback_count = 0;      /* See upload_callback */
124
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
125
/** Calls the server using Ajax, performing an action on the server side.
126
 * Receives the response from the server and performs a refresh of the page
127
 * contents, updating it to display the returned data (such as a directory
128
 * listing, file preview, or editor pane).
129
 * Always makes a POST request.
130
 * No return value.
131
 *
132
 * \param action String. Name of the action to perform, as defined in the
133
 *     fileservice API.
134
 * \param path URL path to make the request to, within the application.
135
 * \param args Argument object, as described in util.parse_url and friends.
136
 *      This should contain the arguments to the action, but NOT the action
137
 *      itself. (Also a minor side-effect; the "args" object will be mutated
138
 *      to include the action attribute).
139
 * \param content_type String, optional.
140
 *      May be "application/x-www-form-urlencoded" or "multipart/form-data".
141
 *      Defaults to "application/x-www-form-urlencoded".
142
 *      "multipart/form-data" is recommended for large uploads.
1326.1.2 by David Coles
Small refactor of browser's JavaScript to allow do_action to be called from
143
 * \param callback, optional.
144
 *      A callback function for after the action has been handled.
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
145
 */
1326.1.2 by David Coles
Small refactor of browser's JavaScript to allow do_action to be called from
146
function do_action(action, path, args, content_type, callback)
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
147
{
148
    args.action = action;
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
149
    /* Callback action, when the server returns */
1326.1.2 by David Coles
Small refactor of browser's JavaScript to allow do_action to be called from
150
    var callback_inner = function(response)
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
151
        {
152
            /* Check for action errors reported by the server, and report them
153
             * to the user */
154
            var error = response.getResponseHeader("X-IVLE-Action-Error");
1169 by William Grant
Don't treat an empty X-IVLE-Action-Error header as an error condition.
155
            if (error != null && error != "")
785 by mattgiuca
fileservice_lib/__init__.py: X-IVLE-Action-Error HTTP response header is now
156
                /* Note: This header (in particular) comes URI-encoded, to
157
                 * allow multi-line error messages. Decode */
158
                alert("Error: " + decodeURIComponent(error.toString()) + ".");
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
159
            /* Now read the response and set up the page accordingly */
1326.1.2 by David Coles
Small refactor of browser's JavaScript to allow do_action to be called from
160
            if (callback != null)
161
                callback(path, response);
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
162
        }
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
163
    /* Call the server and perform the action. This mutates the server. */
1326.1.2 by David Coles
Small refactor of browser's JavaScript to allow do_action to be called from
164
    ajax_call(callback_inner, service_app, path, args, "POST", content_type);
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
165
}
166
167
/** Calls the server using Ajax, requesting a directory listing. This should
168
 * not modify the server in any way. Receives the response from the server and
169
 * performs a refresh of the page contents, updating it to display the
170
 * returned data (such as a directory listing, file preview, or editor pane).
171
 * Called "navigate", can also be used for a simple refresh.
172
 * Always makes a GET request.
173
 * No return value.
174
 */
603 by mattgiuca
Console now starts up in the user's home directory.
175
function navigate(path)
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
176
{
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
177
    callback = function(response)
178
        {
179
            /* Read the response and set up the page accordingly */
789 by mattgiuca
browser.js: Replaced the old "The server returned an invalid directory
180
            handle_response(path, response, false, url.args);
559 by mattgiuca
Major JavaScript refactor: util.ajax_call is now asynchronous, not
181
        }
578 by dcoles
fileservice: Added code to allow browing of past revisons in the File Browser
182
    /* Get any query strings */
183
    url = parse_url(window.location.href);
184
    
602 by mattgiuca
util.js: Added shallow_copy_object function.
185
    /* Call the server and request the listing. */
578 by dcoles
fileservice: Added code to allow browing of past revisons in the File Browser
186
    ajax_call(callback, service_app, path, url.args, "GET");
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
187
}
188
597 by mattgiuca
Major refactor of actions in File browser.
189
/* Refreshes the current view.
190
 * Calls navigate on the current path.
191
 */
192
function refresh()
193
{
865 by wagrant
browser: Warn users before running, serving and refreshing if the file
194
    if (maybe_save('All changes since the last save will be lost!'))
195
        navigate(current_path);
597 by mattgiuca
Major refactor of actions in File browser.
196
}
197
211 by mattgiuca
fileservice/listing: Slight change to date format.
198
/** Determines the "handler type" from a MIME type.
1791.2.8 by David Coles
Add generic <object> media handler for suporting other media types (such as SVG)
199
 * The handler type is a string, either "text", "image", "video", "audio", 
200
 * "object" or "binary".
211 by mattgiuca
fileservice/listing: Slight change to date format.
201
 */
202
function get_handler_type(content_type)
203
{
204
    if (!content_type)
205
        return null;
206
    if (content_type in type_handlers)
207
        return type_handlers[content_type];
208
    else
209
    {   /* Based on the first part of the MIME type */
210
        var handler_type = content_type.split('/')[0];
211
        if (handler_type != "text" && handler_type != "image" &&
1791.2.1 by David Coles
File Browser: File handlers for Image, Audio and Video.
212
            handler_type != "video" && handler_type != "audio")
211 by mattgiuca
fileservice/listing: Slight change to date format.
213
            handler_type = "binary";
214
        return handler_type;
215
    }
216
}
217
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
218
/** Given an HTTP response object, cleans up and rebuilds the contents of the
219
 * page using the response data. This does not navigate away from the page, it
220
 * merely rebuilds most of the data.
221
 * Note that depending on the type of data returned, this could result in a
222
 * directory listing, an image preview, an editor pane, etc.
223
 * Figures out the type and calls the appropriate function.
224
 * \param path URL path which the request was made for. This can (among other
225
 * things) be used to update the URL in the location bar.
226
 * \param response XMLHttpRequest object returned by the server. Should
227
 * contain all the response data.
789 by mattgiuca
browser.js: Replaced the old "The server returned an invalid directory
228
 * \param is_action Boolean. True if this is the response to an action, false
229
 * if this is the response to a simple listing. This is used in handling the
230
 * error.
602 by mattgiuca
util.js: Added shallow_copy_object function.
231
 * \param url_args Arguments dict, for the arguments passed to the URL
232
 * in the browser's address bar (will be forwarded along).
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
233
 */
789 by mattgiuca
browser.js: Replaced the old "The server returned an invalid directory
234
function handle_response(path, response, is_action, url_args)
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
235
{
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
236
    /* TODO: Set location bar to "path" */
211 by mattgiuca
fileservice/listing: Slight change to date format.
237
    current_path = path;
189 by mattgiuca
browser.js: Top-level handler now presents the path nav panel, not dir
238
239
    /* Clear away the existing page contents */
240
    clearpage();
241
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
242
    /* Check the status, and if not 200, read the error and handle this as an
243
     * error. */
244
    if (response.status != 200)
245
    {
246
        var error = response.getResponseHeader("X-IVLE-Return-Error");
247
        if (error == null)
248
            error = response.statusText;
249
        handle_error(error);
250
        return;
251
    }
252
944 by dcoles
Special Home Directory: Work to create a special home directory that shows the
253
    var subjects = null;
1671 by Matt Giuca
browser.js: Fixed check for whether to use specialhome -- now works if the path ends in a '/'. This fixes Launchpad Bug #492510.
254
    /* Remove trailing slash (or path==username won't compare properly) */
255
    if (path[path.length-1] == "/")
256
        path = path.substr(0, path.length-1);
944 by dcoles
Special Home Directory: Work to create a special home directory that shows the
257
    var top_level_dir = path==username;
258
    if (top_level_dir)
259
    {
260
        var req = ajax_call(null, "userservice", "get_enrolments", null, "GET")
261
        subjects = decode_response(req);
262
    }
263
264
602 by mattgiuca
util.js: Added shallow_copy_object function.
265
    /* This will always return a listing, whether it is a dir or a file.
266
     */
267
    var listing = response.responseText;
268
    /* The listing SHOULD be valid JSON text. Parse it into an object. */
269
    try
270
    {
271
        listing = JSON.parse(listing);
272
        file_listing = listing.listing;     /* Global */
273
    }
274
    catch (e)
275
    {
789 by mattgiuca
browser.js: Replaced the old "The server returned an invalid directory
276
        if (is_action)
277
        {
278
            var err = document.createElement("div");
279
            var p = dom_make_text_elem("p", "Error: "
280
                    + "There was an unexpected server error processing "
281
                    + "the selected command.");
282
            err.appendChild(p);
283
            p = dom_make_text_elem("p", "If the problem persists, please "
284
                    + "contact the system administrator.")
285
            err.appendChild(p);
286
            p = document.createElement("p");
287
            var refresh = document.createElement("input");
288
            refresh.setAttribute("type", "button");
289
            refresh.setAttribute("value", "Back to file view");
290
            refresh.setAttribute("onclick", "refresh()");
291
            p.appendChild(refresh);
292
            err.appendChild(p);
293
            handle_error(err);
294
        }
295
        else
296
        {
297
            var err = document.createElement("div");
298
            var p = dom_make_text_elem("p", "Error: "
299
                    + "There was an unexpected server error retrieving "
300
                    + "the requested file or directory.");
301
            err.appendChild(p);
302
            p = dom_make_text_elem("p", "If the problem persists, please "
303
                    + "contact the system administrator.")
304
            err.appendChild(p);
305
            handle_error(err);
306
        }
602 by mattgiuca
util.js: Added shallow_copy_object function.
307
        return;
308
    }
309
    /* Get "." out, it's special */
310
    current_file = file_listing["."];     /* Global */
311
    delete file_listing["."];
312
910 by wagrant
filebrowser_lib: Send the current revision along with the listing if we
313
    if ('revision' in listing)
314
    {
315
        current_revision = listing.revision;
316
    }
317
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
318
    /* Check if this is a directory listing or file contents */
222 by mattgiuca
browser.js:
319
    var isdir = response.getResponseHeader("X-IVLE-Return") == "Dir";
602 by mattgiuca
util.js: Added shallow_copy_object function.
320
    if (isdir)
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
321
    {
980 by dcoles
Files: "Junk" is now only shown when other (non-subject/stuff) files are in the
322
        setup_for_listing();
1670 by Matt Giuca
specialhome.js: Refactor so home_listing (now special_home_listing) is ONLY called if the special home is used, rather than all the time. browser.js: Now calls special_home_listing conditionally.
323
        if (top_level_dir)
324
        {
325
            /* Top-level dir, with subjects */
326
            special_home_listing(listing, subjects, path);
327
        }
328
        else
329
        {
330
            /* Not the top-level dir. Do a normal dir listing. */
331
            handle_dir_listing(path, listing.listing);
332
        }
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
333
    }
334
    else
335
    {
1791.2.7 by David Coles
Change handle_content_response so that we only fetch file contents inside-
336
        /* Read the response and set up the page accordingly */
337
        var content_type = current_file.type;
338
        handle_contents_response(path, content_type, url_args);
339
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
340
    }
597 by mattgiuca
Major refactor of actions in File browser.
341
    update_actions(isdir);
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
342
}
343
1791.2.7 by David Coles
Change handle_content_response so that we only fetch file contents inside-
344
function handle_contents_response(path, content_type)
602 by mattgiuca
util.js: Added shallow_copy_object function.
345
{
346
    /* Treat this as an ordinary file. Get the file type. */
1791.2.7 by David Coles
Change handle_content_response so that we only fetch file contents inside-
347
    //var content_type = response.getResponseHeader("Content-Type");
602 by mattgiuca
util.js: Added shallow_copy_object function.
348
    var handler_type = get_handler_type(content_type);
349
    /* handler_type should now be set to either
1791.2.1 by David Coles
File Browser: File handlers for Image, Audio and Video.
350
     * "text", "image", "video", "audio" or "binary". */
602 by mattgiuca
util.js: Added shallow_copy_object function.
351
    switch (handler_type)
352
    {
353
    case "text":
1791.2.7 by David Coles
Change handle_content_response so that we only fetch file contents inside-
354
        handle_text(path, content_type);
602 by mattgiuca
util.js: Added shallow_copy_object function.
355
        break;
356
    case "image":
1791.2.1 by David Coles
File Browser: File handlers for Image, Audio and Video.
357
        handle_image(path);
358
        break;
359
    case "video":
1833 by William Grant
Merge video and audio handlers, and reword them.
360
        handle_html5_media(path, content_type, "video");
602 by mattgiuca
util.js: Added shallow_copy_object function.
361
        break;
362
    case "audio":
1833 by William Grant
Merge video and audio handlers, and reword them.
363
        handle_html5_media(path, content_type, "audio");
602 by mattgiuca
util.js: Added shallow_copy_object function.
364
        break;
1791.2.8 by David Coles
Add generic <object> media handler for suporting other media types (such as SVG)
365
    case "object":
366
        handle_object(path, content_type);
367
        break;
602 by mattgiuca
util.js: Added shallow_copy_object function.
368
    case "binary":
369
        handle_binary(path);
370
        break;
371
    }
372
}
373
622 by mattgiuca
browser.js: Reinstated upload_callback (previously removed from listing.js).
374
/* Called when a form upload comes back (from an iframe).
375
 * Refreshes the page.
376
 */
377
function upload_callback()
378
{
379
    /* This has a pretty nasty hack, which happens to work.
380
     * upload_callback is set as the "onload" callback for the iframe which
381
     * receives the response from the server for uploading a file.
382
     * This means it gets called twice. Once when initialising the iframe, and
383
     * a second time when the actual response comes back.
384
     * All we want to do is call navigate to refresh the page. But we CAN'T do
385
     * that on the first load or it will just go into an infinite cycle of
386
     * refreshing. We need to refresh the page ONLY on the second refresh.
387
     * upload_callback_count is reset to 0 just before the iframe is created.
388
     */
389
    upload_callback_count++;
390
    if (upload_callback_count >= 2)
838 by wagrant
browser.js: Clear the file upload path when an upload finishes.
391
    {
1089 by chadnickbok
Fixes Issue #14
392
        myFrame = frames['upload_iframe'].document;
1337 by William Grant
In the filebrowser upload callback, don't assume that the browser will generate a head element.
393
        /* Browsers will turn the raw returned JSON into an HTML document. We
394
         * need to get the <pre> from inside the <body>, and look at its text.
395
         */
1791 by David Coles
Use innerText || innerContent to get contents of iframe. Should prevent an odd
396
        var pre = myFrame.firstChild.getElementsByTagName(
397
            'body')[0].firstChild;
398
        var data = pre.innerText || pre.textContent;
1089 by chadnickbok
Fixes Issue #14
399
        data = JSON.parse(data);
400
        if ('Error' in data)
401
            alert("Error: " + decodeURIComponent(data['Error']));
838 by wagrant
browser.js: Clear the file upload path when an upload finishes.
402
        document.getElementsByName('data')[0].value = '';
622 by mattgiuca
browser.js: Reinstated upload_callback (previously removed from listing.js).
403
        refresh();
838 by wagrant
browser.js: Clear the file upload path when an upload finishes.
404
    }
622 by mattgiuca
browser.js: Reinstated upload_callback (previously removed from listing.js).
405
}
406
188 by mattgiuca
browser.js: Can now (shakily) handle directory listings. (lots of code!)
407
/** Deletes all "dynamic" content on the page.
408
 * This returns the page back to the state it is in when the HTML arrives to
409
 * the browser, ready for another handler to populate it.
410
 */
411
function clearpage()
412
{
203 by mattgiuca
browser: Removed all directory-listing specific HTML from the Python-generated
413
    dom_removechildren(document.getElementById("filesbody"));
414
}
415
865 by wagrant
browser: Warn users before running, serving and refreshing if the file
416
/* Checks if a file needs to be saved. If it does, the user will be asked
417
 * if they want to continue anyway. The caller must specify a warning
418
 * sentence which indicates the consequences of continuing.
419
 * Returns true if we should continue, and false if we should not.
420
 */
421
function maybe_save(warning)
422
{
423
    if (warning == null) warning = '';
1628 by Matt Giuca
browser.js: Added null check to avoid error if the page had an error. Fixes Launchpad Bug #523601.
424
    if (current_file == null || current_file.isdir) return true;
865 by wagrant
browser: Warn users before running, serving and refreshing if the file
425
    if (document.getElementById("save_button").disabled) return true;
426
    return confirm("This file has unsaved changes. " + warning +
427
                   "\nAre you sure you wish to continue?");
428
}
429
203 by mattgiuca
browser: Removed all directory-listing specific HTML from the Python-generated
430
/** Deletes all "dynamic" content on the page necessary to navigate from
431
 * one directory listing to another (does not clear as much as clearpage
432
 * does).
433
 * This is the equivalent of calling clearpage() then
434
 * setup_for_dir_listing(), assuming the page is already on a dir listing.
435
 */
436
function clearpage_dir()
437
{
188 by mattgiuca
browser.js: Can now (shakily) handle directory listings. (lots of code!)
438
    dom_removechildren(document.getElementById("path"));
439
    dom_removechildren(document.getElementById("files"));
440
    dom_removechildren(document.getElementById("sidepanel"));
441
}
442
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
443
/*** HANDLERS for different types of responses (such as dir listing, file,
444
 * etc). */
445
789 by mattgiuca
browser.js: Replaced the old "The server returned an invalid directory
446
/* handle_error.
447
 * message may either be a string, or a DOM node, which will be placed inside
448
 * a div.
449
 */
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
450
function handle_error(message)
451
{
205 by mattgiuca
browser.js: Added appropriate handlers for error, text, and binary data.
452
    var files = document.getElementById("filesbody");
789 by mattgiuca
browser.js: Replaced the old "The server returned an invalid directory
453
    var txt_elem;
454
    if (typeof(message) == "string")
455
    {
456
        txt_elem = dom_make_text_elem("div", "Error: "
457
                   + message.toString() + ".")
458
    }
459
    else
460
    {
461
        /* Assume message is a DOM node */
462
        txt_elem = document.createElement("div");
463
        txt_elem.appendChild(message);
464
    }
205 by mattgiuca
browser.js: Added appropriate handlers for error, text, and binary data.
465
    txt_elem.setAttribute("class", "padding error");
466
    files.appendChild(txt_elem);
188 by mattgiuca
browser.js: Can now (shakily) handle directory listings. (lots of code!)
467
}
468
910 by wagrant
filebrowser_lib: Send the current revision along with the listing if we
469
/** Given a path, filename and optional revision, returns a URL to open that
470
 *  revision of that file.
471
 */
472
function build_revision_url(path, filename, revision)
473
{
474
    bits = {'path': app_path(this_app, path, filename)};
475
    if (current_revision)
476
    {
477
        bits['query_string'] = 'r=' + revision;
478
    }
479
    return build_url(bits);
480
}
481
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
482
/** Given a mime type, returns the path to the icon.
483
 * \param type String, Mime type.
484
 * \param sizelarge Boolean, optional.
485
 * \return Path to the icon. Has applied make_path, so it is relative to site
486
 * root.
487
 */
488
function mime_type_to_icon(type, sizelarge)
489
{
490
    var filename;
491
    if (type in type_icons)
492
        filename = type_icons[type];
493
    else
494
        filename = default_type_icon;
495
    if (sizelarge)
496
        return make_path(path_join(type_icons_path_large, filename));
497
    else
498
        return make_path(path_join(type_icons_path, filename));
499
}
500
501
/** Given an svnstatus, returns the path to the icon.
502
 * \param type String, svn status.
503
 * \return Path to the icon. Has applied make_path, so it is relative to site
230 by mattgiuca
Removed "unversioned" icon from subversion status. Now unversioned files do
504
 * root. May return null to indicate no SVN icon.
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
505
 */
506
function svnstatus_to_icon(svnstatus)
507
{
508
    var filename;
509
    if (svnstatus in svn_icons)
510
        filename = svn_icons[svnstatus];
511
    else
512
        filename = default_svn_icon;
230 by mattgiuca
Removed "unversioned" icon from subversion status. Now unversioned files do
513
    if (filename == null) return null;
190 by mattgiuca
util: Added function dom_make_img, creates <img> elements.
514
    return make_path(path_join(svn_icons_path, filename));
515
}
516
213 by mattgiuca
Fileservice / Files (Python and JS files):
517
/** Given an svnstatus, returns the "nice" string.
518
 */
519
function svnstatus_to_string(svnstatus)
520
{
521
    if (svnstatus in svn_nice)
522
        return svn_nice[svnstatus];
523
    else
524
        return default_svn_nice;
525
}
526
1662 by Matt Giuca
browser.js, listing.js: Abstract testing svn status against 'unversioned' to svnstatus_versioned function.
527
/** Returns true if a file is versioned (not unversioned or ignored).
528
 */
529
function svnstatus_versioned(svnstatus)
530
{
1663 by Matt Giuca
Added handlers and documentation for Subversion status 'ignored' (we call them 'Temporary file (ignored)'. This was previously handled as an 'unknown status'. Ignored files now can't have svn actions done on them either. This fixes Launchpad bug #526220.
531
    return svnstatus != "unversioned" && svnstatus != "ignored";
1662 by Matt Giuca
browser.js, listing.js: Abstract testing svn status against 'unversioned' to svnstatus_versioned function.
532
}
533
183 by mattgiuca
browser: Added top level of response handling. Now determines handler type and
534
/** Displays a download link to the binary file.
535
 */
536
function handle_binary(path)
537
{
1791.2.2 by David Coles
File Browser: Don't show actions2_file for anything but text editor and
538
    // Disable save button
539
    using_codepress = false;
1831 by William Grant
Fix HTML5 media handlers function call. It was renamed in the CodeMirror branch.
540
    disable_save();
1791.2.2 by David Coles
File Browser: Don't show actions2_file for anything but text editor and
541
542
    // Show download link
205 by mattgiuca
browser.js: Added appropriate handlers for error, text, and binary data.
543
    var files = document.getElementById("filesbody");
544
    var div = document.createElement("div");
545
    files.appendChild(div);
546
    div.setAttribute("class", "padding");
1661 by Matt Giuca
browser.js: Fixed generation of links in file browser to Serve, Download and Share-this-file links containing special URI characters. Now properly URL-encoded. Added util.js app_url and public_app_url, replacing calls to app_path and public_app_path. Fixes Launchpad bug #524176.
547
    var download_link = app_url(download_app, path);
205 by mattgiuca
browser.js: Added appropriate handlers for error, text, and binary data.
548
    var par1 = dom_make_text_elem("p",
549
        "The file " + path + " is a binary file. To download this file, " +
550
        "click the following link:");
551
    var par2 = dom_make_link_elem("p",
552
        "Download " + path, "Download " + path, download_link);
553
    div.appendChild(par1);
554
    div.appendChild(par2);
181 by mattgiuca
browser.js: Added functions do_action, navigate, handle_response (stubs).
555
}
556
1791.2.1 by David Coles
File Browser: File handlers for Image, Audio and Video.
557
/** Displays an image file.
558
 */
559
function handle_image(path)
560
{
1791.2.5 by David Coles
File Browser: Rewrite using text() to avoid HTML injection and allow for
561
    /* Disable save button */
1791.2.2 by David Coles
File Browser: Don't show actions2_file for anything but text editor and
562
    using_codepress = false;
1831 by William Grant
Fix HTML5 media handlers function call. It was renamed in the CodeMirror branch.
563
    disable_save();
1791.2.2 by David Coles
File Browser: Don't show actions2_file for anything but text editor and
564
1791.2.5 by David Coles
File Browser: Rewrite using text() to avoid HTML injection and allow for
565
    /* URL */
1791.2.9 by David Coles
Use "?return=contents" URL instead of '/download/' since "Content-Disposition:
566
    var url = app_url(service_app, path) + "?return=contents";
1791.2.5 by David Coles
File Browser: Rewrite using text() to avoid HTML injection and allow for
567
568
    /* Image Preview */
569
    var img = $("<img />");
570
    img.attr("alt", path);
571
    img.attr("src", url);
572
573
    /* Show Preview */
574
    var div = $('<div class="padding" />');
575
    div.append('<h1>Image Preview</h1>');
576
    div.append(img);
577
    $("#filesbody").append(div);
1791.2.1 by David Coles
File Browser: File handlers for Image, Audio and Video.
578
}
579
1833 by William Grant
Merge video and audio handlers, and reword them.
580
/* Displays a media file using an HTML5 <audio> or <video> tag.
581
 * Falls back to <object> if the format is unsupported.
582
 */
583
function handle_html5_media(path, type, tag_name)
584
{
585
    /* Disable save button and hide the save panel */
586
    using_codepress = false;
587
    disable_save();
588
589
    /* URL */
590
    var url = app_url(service_app, path) + "?return=contents";
591
    var download_url = app_url(download_app, path);
592
593
    /* Fallback download link */
594
    var link = $(
595
        '<p>Could not play ' + tag_name + ' file. ' +
596
        'Try <a>downloading it</a> instead.</p>');
597
    link.find('a').attr("href", download_url);
598
599
    /* HTML 5 media element */
600
    var html5_element = $(
601
        '<' + tag_name + ' controls="true" autoplay="true" />');
602
    html5_element.attr("src", url);
603
    var support = (html5_element[0].canPlayType &&
604
                   html5_element[0].canPlayType(type));
605
606
    /* If the browser thinks it might be able to play it, use the HTML5
607
     * element. Otherwise, fall back to an <object>, which might work.
608
     */
609
    if (support == "probably" || support == "maybe") {
610
        var element = html5_element;
611
    } else {
612
        var element = $('<object />');
613
        element.attr("type", type);
614
        element.attr("data", url);
615
    }
616
    element.append(link);
617
618
    /* Show Preview */
619
    var div = $('<div class="padding" />');
620
    div.append('<h1>File preview</h1>');
621
    div.append(element);
1791.2.5 by David Coles
File Browser: Rewrite using text() to avoid HTML injection and allow for
622
    $("#filesbody").append(div);
1791.2.1 by David Coles
File Browser: File handlers for Image, Audio and Video.
623
}
624
1791.2.8 by David Coles
Add generic <object> media handler for suporting other media types (such as SVG)
625
/** Display generic object content
626
 */
627
function handle_object(path, content_type)
628
{
629
    /* Disable save button and hide the save panel */
630
    using_codepress = false;
1831 by William Grant
Fix HTML5 media handlers function call. It was renamed in the CodeMirror branch.
631
    disable_save();
1791.2.8 by David Coles
Add generic <object> media handler for suporting other media types (such as SVG)
632
633
    /* URL */
634
    var url = app_url(service_app, path) + "?return=contents";
635
    var download_url = app_url(download_app, path);
636
637
    /* Fallback Download Link */
638
    var link = $('<p><a /></p>');
639
    var a = link.find('a');
640
    a.attr("href", download_url);
641
    a.text("Download " + path);
642
643
    /* Object Tag */
644
    var obj = $('<object width="100%" height="500px" />');
645
    obj.attr("type", content_type);
646
    obj.attr("data", url);
647
    obj.append('Could not load object');
648
649
    /* Show Preview */
650
    var div = $('<div class="padding" />');
651
    div.append('<h1>Preview</h1>');
652
    div.append(obj);
653
    div.append(link);
654
    $("#filesbody").append(div);
655
}
656
863 by wagrant
browser: Let set_action_state take an Array of names as well. We now
657
/* Enable or disable actions1 moreactions actions. Takes either a single
658
 * name, or an array of them.*/
908 by wagrant
browser: Link breadcrumbs to the current revision.
659
function set_action_state(names, which, allow_on_revision)
862 by wagrant
browser: Refactor the client-side actions1 processing! Kill off 100 lines
660
{
863 by wagrant
browser: Let set_action_state take an Array of names as well. We now
661
    if (!(names instanceof Array)) names = Array(names);
662
663
    for (var i=0; i < names.length; i++)
664
    {
665
        element = document.getElementById('act_' + names[i]);
908 by wagrant
browser: Link breadcrumbs to the current revision.
666
        if (which &&
667
            !(current_file.svnstatus == 'revision' && !allow_on_revision))
863 by wagrant
browser: Let set_action_state take an Array of names as well. We now
668
        {
669
            /* Enabling */
670
            element.setAttribute("class", "choice");
671
            element.removeAttribute("disabled");
672
        }
673
        else
674
        {
675
            /* Disabling */
676
            element.setAttribute("class", "disabled");
677
            element.setAttribute("disabled", "disabled");
678
        }
862 by wagrant
browser: Refactor the client-side actions1 processing! Kill off 100 lines
679
    }
680
}
681
1086 by chadnickbok
This commit fixes issue #10 and part of issue #9
682
/* Updates the list of available actions based on files selected */
597 by mattgiuca
Major refactor of actions in File browser.
683
function update_actions()
684
{
685
    var file;
686
    var numsel = selected_files.length;
1086 by chadnickbok
This commit fixes issue #10 and part of issue #9
687
    var svn_selection = false;
688
    
689
    if (numsel > 0)
690
    {
691
        svn_selection = true;
692
        for (var i = 0; i < selected_files.length; i++){
1662 by Matt Giuca
browser.js, listing.js: Abstract testing svn status against 'unversioned' to svnstatus_versioned function.
693
            if (!svnstatus_versioned(file_listing[selected_files[i]].svnstatus))
1086 by chadnickbok
This commit fixes issue #10 and part of issue #9
694
            {
1662 by Matt Giuca
browser.js, listing.js: Abstract testing svn status against 'unversioned' to svnstatus_versioned function.
695
                svn_selection = false;
1086 by chadnickbok
This commit fixes issue #10 and part of issue #9
696
            }
697
        }
698
    }
699
    
597 by mattgiuca
Major refactor of actions in File browser.
700
    if (numsel <= 1)
701
    {
702
        if (numsel == 0)
703
        {
704
            /* Display information about the current directory instead */
705
            filename = path_basename(current_path);
602 by mattgiuca
util.js: Added shallow_copy_object function.
706
            file = current_file;
597 by mattgiuca
Major refactor of actions in File browser.
707
        }
708
        else if (numsel == 1)
709
        {
710
            filename = selected_files[0];
711
            file = file_listing[filename];
712
        }
713
714
        /* Update each action node in the topbar.
715
         * This includes enabling/disabling actions as appropriate, and
716
         * setting href/onclick attributes. */
717
    }
718
719
    /* Open */
720
    /* Available if exactly one file is selected */
721
    var open = document.getElementById("act_open");
722
    if (numsel == 1)
723
    {
724
        open.setAttribute("class", "choice");
725
        if (file.isdir)
726
            open.setAttribute("title",
727
                "Navigate to this directory in the file browser");
728
        else
729
            open.setAttribute("title",
730
                "Edit or view this file");
910 by wagrant
filebrowser_lib: Send the current revision along with the listing if we
731
        open.setAttribute("href", build_revision_url(current_path, filename,
732
                                                     current_revision));
597 by mattgiuca
Major refactor of actions in File browser.
733
    }
734
    else
735
    {
736
        open.setAttribute("class", "disabled");
737
        open.removeAttribute("title");
738
        open.removeAttribute("href");
739
    }
740
741
    /* Serve */
775 by mattgiuca
browser.js: Updated logic to decide when to enable/disable certain actions.
742
    /* Available if zero or one files are selected,
597 by mattgiuca
Major refactor of actions in File browser.
743
     * and only if this is a file, not a directory */
744
    var serve = document.getElementById("act_serve");
908 by wagrant
browser: Link breadcrumbs to the current revision.
745
    if (numsel <= 1 && !file.isdir && current_file.svnstatus != 'revision')
597 by mattgiuca
Major refactor of actions in File browser.
746
    {
747
        serve.setAttribute("class", "choice");
865 by wagrant
browser: Warn users before running, serving and refreshing if the file
748
        serve.setAttribute("onclick",
749
              "return maybe_save('The last saved version will be served.')");
775 by mattgiuca
browser.js: Updated logic to decide when to enable/disable certain actions.
750
        if (numsel == 0)
751
            serve.setAttribute("href",
1661 by Matt Giuca
browser.js: Fixed generation of links in file browser to Serve, Download and Share-this-file links containing special URI characters. Now properly URL-encoded. Added util.js app_url and public_app_url, replacing calls to app_path and public_app_path. Fixes Launchpad bug #524176.
752
                app_url(serve_app, current_path));
775 by mattgiuca
browser.js: Updated logic to decide when to enable/disable certain actions.
753
        else
754
            serve.setAttribute("href",
1661 by Matt Giuca
browser.js: Fixed generation of links in file browser to Serve, Download and Share-this-file links containing special URI characters. Now properly URL-encoded. Added util.js app_url and public_app_url, replacing calls to app_path and public_app_path. Fixes Launchpad bug #524176.
755
                app_url(serve_app, current_path, filename));
597 by mattgiuca
Major refactor of actions in File browser.
756
    }
757
    else
758
    {
759
        serve.setAttribute("class", "disabled");
760
        serve.removeAttribute("href");
865 by wagrant
browser: Warn users before running, serving and refreshing if the file
761
        serve.removeAttribute("onclick");
597 by mattgiuca
Major refactor of actions in File browser.
762
    }
763
764
    /* Run */
765
    /* Available if exactly one file is selected,
766
     * and it is a Python file.
767
     */
713 by dcoles
browser: Added console and run button to allow Python files to be executed in
768
    var run = document.getElementById("act_run");
769
     
1086 by chadnickbok
This commit fixes issue #10 and part of issue #9
770
    if (numsel <= 1 && !file.isdir && file.type == "text/x-python" 
771
            && current_file.svnstatus != 'revision')
873 by dcoles
Filebrowser: Clean up the javascript code a bit.
772
    {
773
        if (numsel == 0)
774
        {
775
            // In the edit window
776
            var localpath = path_join('/home', current_path);
777
        }
778
        else
779
        {
780
            // In the browser window
781
            var localpath = path_join('/home', current_path, filename);
782
        }
783
        run.setAttribute("class", "choice");
713 by dcoles
browser: Added console and run button to allow Python files to be executed in
784
        run.setAttribute("onclick", "runfile('" + localpath + "')");
785
    }
786
    else
787
    {
788
        run.setAttribute("class", "disabled");
789
        run.removeAttribute("onclick");
790
    }
597 by mattgiuca
Major refactor of actions in File browser.
791
792
    /* Download */
908 by wagrant
browser: Link breadcrumbs to the current revision.
793
    /* Always available for current files.
597 by mattgiuca
Major refactor of actions in File browser.
794
     * If 0 files selected, download the current file or directory as a ZIP.
795
     * If 1 directory selected, download it as a ZIP.
796
     * If 1 non-directory selected, download it.
797
     * If >1 files selected, download them all as a ZIP.
798
     */
799
    var download = document.getElementById("act_download");
908 by wagrant
browser: Link breadcrumbs to the current revision.
800
    if (current_file.svnstatus == 'revision')
801
    {
802
        download.setAttribute("class", "disabled");
803
        download.removeAttribute("onclick");
804
    }
805
    else if (numsel <= 1)
806
    {
807
        download.setAttribute("class", "choice")
597 by mattgiuca
Major refactor of actions in File browser.
808
        if (numsel == 0)
809
        {
810
            download.setAttribute("href",
1661 by Matt Giuca
browser.js: Fixed generation of links in file browser to Serve, Download and Share-this-file links containing special URI characters. Now properly URL-encoded. Added util.js app_url and public_app_url, replacing calls to app_path and public_app_path. Fixes Launchpad bug #524176.
811
                app_url(download_app, current_path));
597 by mattgiuca
Major refactor of actions in File browser.
812
            if (file.isdir)
813
                download.setAttribute("title",
814
                    "Download the current directory as a ZIP file");
815
            else
816
                download.setAttribute("title",
817
                    "Download the current file");
818
        }
819
        else
820
        {
821
            download.setAttribute("href",
1661 by Matt Giuca
browser.js: Fixed generation of links in file browser to Serve, Download and Share-this-file links containing special URI characters. Now properly URL-encoded. Added util.js app_url and public_app_url, replacing calls to app_path and public_app_path. Fixes Launchpad bug #524176.
822
                app_url(download_app, current_path, filename));
597 by mattgiuca
Major refactor of actions in File browser.
823
            if (file.isdir)
824
                download.setAttribute("title",
825
                    "Download the selected directory as a ZIP file");
826
            else
827
                download.setAttribute("title",
828
                    "Download the selected file");
829
        }
830
    }
831
    else
832
    {
833
        /* Make a query string with all the files to download */
1661 by Matt Giuca
browser.js: Fixed generation of links in file browser to Serve, Download and Share-this-file links containing special URI characters. Now properly URL-encoded. Added util.js app_url and public_app_url, replacing calls to app_path and public_app_path. Fixes Launchpad bug #524176.
834
        var dlpath = app_url(download_app, current_path) + "?";
597 by mattgiuca
Major refactor of actions in File browser.
835
        for (var i=0; i<numsel; i++)
836
            dlpath += "path=" + encodeURIComponent(selected_files[i]) + "&";
837
        dlpath = dlpath.substr(0, dlpath.length-1);
908 by wagrant
browser: Link breadcrumbs to the current revision.
838
        download.setAttribute("class", "choice")
597 by mattgiuca
Major refactor of actions in File browser.
839
        download.setAttribute("href", dlpath);
840
        download.setAttribute("title",
841
            "Download the selected files as a ZIP file");
842
    }
843
844
    /* Refresh - No changes required */
845
846
    /* Publish and Submit */
847
    /* If this directory is under subversion and selected/unselected file is a
848
     * directory. */
849
    var publish = document.getElementById("act_publish");
850
    var submit = document.getElementById("act_submit");
862 by wagrant
browser: Refactor the client-side actions1 processing! Kill off 100 lines
851
    var pubcond = numsel <= 1 && file.isdir;
852
    if (pubcond)
597 by mattgiuca
Major refactor of actions in File browser.
853
    {
727 by dcoles
Browser: Added UI code to let you publish and unpublish folders
854
        /* If this dir is already published, call it "Unpublish" */
855
        if (file.published)
856
        {
857
            publish.setAttribute("value", "unpublish");
858
            publish.setAttribute("title" ,"Make it so this directory "
859
                + "can not be seen by anyone on the web");
1171 by William Grant
Replace all uses of .textContent with .nodeValue.
860
            publish.firstChild.nodeValue = "Unpublish";
727 by dcoles
Browser: Added UI code to let you publish and unpublish folders
861
        } else {
862
            publish.setAttribute("value", "publish");
863
            publish.setAttribute("title","Make it so this directory "
864
                + "can be seen by anyone on the web");
1171 by William Grant
Replace all uses of .textContent with .nodeValue.
865
            publish.firstChild.nodeValue = "Publish";
727 by dcoles
Browser: Added UI code to let you publish and unpublish folders
866
        }
862 by wagrant
browser: Refactor the client-side actions1 processing! Kill off 100 lines
867
    }
863 by wagrant
browser: Let set_action_state take an Array of names as well. We now
868
    set_action_state(["publish", "submit"], pubcond);
597 by mattgiuca
Major refactor of actions in File browser.
869
870
    /* Share */
862 by wagrant
browser: Refactor the client-side actions1 processing! Kill off 100 lines
871
    /* If exactly 1 non-directory file is selected, and its parent
597 by mattgiuca
Major refactor of actions in File browser.
872
     * directory is published.
873
     */
862 by wagrant
browser: Refactor the client-side actions1 processing! Kill off 100 lines
874
    set_action_state("share", numsel == 1 && !file.isdir &&
875
                     current_file.published);
597 by mattgiuca
Major refactor of actions in File browser.
876
877
    /* Rename */
878
    /* If exactly 1 file is selected */
862 by wagrant
browser: Refactor the client-side actions1 processing! Kill off 100 lines
879
    set_action_state("rename", numsel == 1);
597 by mattgiuca
Major refactor of actions in File browser.
880
881
    /* Delete, cut, copy */
882
    /* If >= 1 file is selected */
863 by wagrant
browser: Let set_action_state take an Array of names as well. We now
883
    set_action_state(["delete", "cut", "copy"], numsel >= 1);
597 by mattgiuca
Major refactor of actions in File browser.
884
885
    /* Paste, new file, new directory, upload */
775 by mattgiuca
browser.js: Updated logic to decide when to enable/disable certain actions.
886
    /* Disable if the current file is not a directory */
863 by wagrant
browser: Let set_action_state take an Array of names as well. We now
887
    set_action_state(["paste", "newfile", "mkdir", "upload"], current_file.isdir);
597 by mattgiuca
Major refactor of actions in File browser.
888
889
    /* Subversion actions */
829 by wagrant
Add an svndiff action, and give it an option in the action listbox.
890
    /* These are only useful if we are in a versioned directory and have some
891
     * files selected. */
1804 by David Coles
Added Subversion rename to Filebrowser.
892
    set_action_state(["svnrename"], numsel == 1 && current_file.svnstatus);
1167 by William Grant
Remove an extra comma from browser.js.
893
    set_action_state(["svnadd"], numsel >= 1 && current_file.svnstatus);
1664 by Matt Giuca
browser.js: Adjusted condition for enabling "Commit" action; now allowed if
894
    /* And these are only useful is ALL the selected files are versioned */
895
    set_action_state(["svnremove", "svnrevert", "svncopy", "svncut"],
896
            numsel >= 1 && current_file.svnstatus && svn_selection);
897
    /* Commit is useful if ALL selected files are versioned, or the current
898
     * directory is versioned */
899
    set_action_state(["svncommit"], current_file.svnstatus &&
900
            (numsel >= 1 && svn_selection || numsel == 0));
901
918 by wagrant
browser: Expose svn update functionality. This brings a need for an
902
    /* Diff, log and update only support one path at the moment, so we must
903
     * have 0 or 1 versioned files selected. If 0, the directory must be
904
     * versioned. */
881 by wagrant
browser.js: Support svndiff and svnlog for versioned directories. Also
905
    single_versioned_path = (
906
         (
907
          (numsel == 1 && (svnst = file_listing[selected_files[0]].svnstatus)) ||
908
          (numsel == 0 && (svnst = current_file.svnstatus))
1662 by Matt Giuca
browser.js, listing.js: Abstract testing svn status against 'unversioned' to svnstatus_versioned function.
909
         ) && svnstatus_versioned(svnst));
918 by wagrant
browser: Expose svn update functionality. This brings a need for an
910
    set_action_state(["svndiff", "svnupdate"], single_versioned_path);
908 by wagrant
browser: Link breadcrumbs to the current revision.
911
919 by wagrant
fileservice_lib: Implement "svn resolved".
912
    /* We can resolve if we have a file selected and it is conflicted. */
913
    set_action_state("svnresolved", single_versioned_path && numsel == 1 && svnst == "conflicted");
914
908 by wagrant
browser: Link breadcrumbs to the current revision.
915
    /* Log should be available for revisions as well. */
916
    set_action_state("svnlog", single_versioned_path, true);
862 by wagrant
browser: Refactor the client-side actions1 processing! Kill off 100 lines
917
1318.1.2 by David Coles
Add Subversion Cleanup to web UI
918
    /* Cleanup should be available for revisions as well. */
919
    set_action_state("svncleanup", single_versioned_path, true);
920
1165.1.33 by William Grant
Enable the Submit filebrowser action only when we have exactly one target
921
    single_ivle_versioned_path = (
922
         (
923
          (numsel == 1 && (stat = file_listing[selected_files[0]])) ||
924
          (numsel == 0 && (stat = current_file))
1662 by Matt Giuca
browser.js, listing.js: Abstract testing svn status against 'unversioned' to svnstatus_versioned function.
925
         ) && svnstatus_versioned(stat.svnstatus)
1165.1.37 by William Grant
Check that stat.svnurl exists before using parts of it to enable the Submit action.
926
           && stat.svnurl
1165.1.33 by William Grant
Enable the Submit filebrowser action only when we have exactly one target
927
           && stat.svnurl.substr(0, svn_base.length) == svn_base);
928
    set_action_state(["submit"], single_ivle_versioned_path);
929
777 by mattgiuca
browser: Now hides the "More actions" box altogether if the current file is
930
    /* There is currently nothing on the More Actions menu of use
931
     * when the current file is not a directory. Hence, just remove
932
     * it entirely.
933
     * (This makes some of the above decisions somewhat redundant).
834 by wagrant
Let the client decide whether to show file or directory actions2, as
934
     * We also take this opportunity to show the appropriate actions2
935
     * bar for this path. It should either be a save or upload widget.
777 by mattgiuca
browser: Now hides the "More actions" box altogether if the current file is
936
     */
834 by wagrant
Let the client decide whether to show file or directory actions2, as
937
    if (current_file.isdir)
938
    {
939
        var actions2_directory = document.getElementById("actions2_directory");
940
        actions2_directory.setAttribute("style", "display: inline;");
911 by wagrant
browser: Hide 'More Actions' by default. It will be shown by JS when
941
        var moreactions = document.getElementById("moreactions_area");
942
        moreactions.setAttribute("style", "display: inline;");
834 by wagrant
Let the client decide whether to show file or directory actions2, as
943
    }
777 by mattgiuca
browser: Now hides the "More actions" box altogether if the current file is
944
597 by mattgiuca
Major refactor of actions in File browser.
945
    return;
946
}
947
948
/** Event handler for when an item of the "More actions..." dropdown box is
949
 * selected. Performs the selected action. */
950
function handle_moreactions()
951
{
952
    var moreactions = document.getElementById("moreactions");
953
    if (moreactions.value == "top")
954
        return;
955
    var selectedaction = moreactions.value;
956
    /* Reset to "More actions..." */
957
    moreactions.selectedIndex = 0;
958
607 by mattgiuca
browser/browser.js: All the actions in "more actions" now actually take
959
    /* If 0 files selected, filename is the name of the current dir.
960
     * If 1 file selected, filename is that file.
961
     */
962
    if (selected_files.length == 0)
963
        filename = path_basename(current_path);
964
    else if (selected_files.length == 1)
965
        filename = selected_files[0];
966
    else
967
        filename = null;
968
597 by mattgiuca
Major refactor of actions in File browser.
969
    /* Now handle the selected action */
607 by mattgiuca
browser/browser.js: All the actions in "more actions" now actually take
970
    switch(selectedaction)
971
    {
972
    case "publish":
973
        action_publish(selected_files);
974
        break;
975
    case "unpublish":
976
        action_unpublish(selected_files);
977
        break;
978
    case "share":
1661 by Matt Giuca
browser.js: Fixed generation of links in file browser to Serve, Download and Share-this-file links containing special URI characters. Now properly URL-encoded. Added util.js app_url and public_app_url, replacing calls to app_path and public_app_path. Fixes Launchpad bug #524176.
979
        window.open(public_app_url("~" + current_path, filename), 'share')
607 by mattgiuca
browser/browser.js: All the actions in "more actions" now actually take
980
        break;
981
    case "submit":
1165.1.35 by William Grant
Implement the Submit filebrowser action.
982
        if (selected_files.length == 1)
983
            stat = file_listing[selected_files[0]];
984
        else
985
            stat = current_file;
1642 by Matt Giuca
browser.js: submit now decodes the URL of a file before submitting it. This ensures that files with 'special' characters are treated correctly before being sent in a POST request (since the URLs come URL-encoded, not decoding them first would result in double-encoding). Fixes Launchpad bug #523656.
986
        url = stat.svnurl.substr(svn_base.length);      // URL-encoded
987
        path = decodeURIComponent(url);
1165.1.40 by William Grant
When submitting, query the server about the latest revision of the path.
988
989
        /* The working copy might not have an up-to-date version of the
990
         * directory. While submitting like this could yield unexpected
991
         * results, we should really submit the latest revision to minimise
992
         * terrible mistakes - so we run off and ask fileservice for the
993
         * latest revision.*/
994
        $.post(app_path(service_app, current_path),
995
            {"action": "svnrepostat", "path": path},
996
            function(result)
997
            {
1642 by Matt Giuca
browser.js: submit now decodes the URL of a file before submitting it. This ensures that files with 'special' characters are treated correctly before being sent in a POST request (since the URLs come URL-encoded, not decoding them first would result in double-encoding). Fixes Launchpad bug #523656.
998
                window.location = path_join(app_path('+submit'), url) + '?revision=' + result.svnrevision;
1165.1.40 by William Grant
When submitting, query the server about the latest revision of the path.
999
            },
1000
            "json");
1001
607 by mattgiuca
browser/browser.js: All the actions in "more actions" now actually take
1002
        break;
1003
    case "rename":
1004
        action_rename(filename);
1005
        break;
1006
    case "delete":
921 by wagrant
fileservice_lib, browser: Rename the old remove action to delete, to
1007
        action_delete(selected_files);
607 by mattgiuca
browser/browser.js: All the actions in "more actions" now actually take
1008
        break;
1009
    case "copy":
1010
        action_copy(selected_files);
1011
        break;
1012
    case "cut":
1013
        action_cut(selected_files);
1014
        break;
1015
    case "paste":
1016
        action_paste();
1017
        break;
1018
    case "newfile":
611 by mattgiuca
"New File" now works. (This is a MUCH better replacement for having to go to
1019
        action_newfile();
607 by mattgiuca
browser/browser.js: All the actions in "more actions" now actually take
1020
        break;
1021
    case "mkdir":
1022
        action_mkdir();
1023
        break;
1024
    case "upload":
1025
        show_uploadpanel(true);
1026
        break;
1027
    case "svnadd":
1028
        action_add(selected_files);
1029
        break;
921 by wagrant
fileservice_lib, browser: Rename the old remove action to delete, to
1030
    case "svnremove":
1804 by David Coles
Added Subversion rename to Filebrowser.
1031
        action_svnremove(selected_files);
1032
        break;
1033
    case "svnrename":
1034
        action_svnrename(selected_files);
921 by wagrant
fileservice_lib, browser: Rename the old remove action to delete, to
1035
        break;
607 by mattgiuca
browser/browser.js: All the actions in "more actions" now actually take
1036
    case "svnrevert":
1037
        action_revert(selected_files);
1038
        break;
829 by wagrant
Add an svndiff action, and give it an option in the action listbox.
1039
    case "svndiff":
1661 by Matt Giuca
browser.js: Fixed generation of links in file browser to Serve, Download and Share-this-file links containing special URI characters. Now properly URL-encoded. Added util.js app_url and public_app_url, replacing calls to app_path and public_app_path. Fixes Launchpad bug #524176.
1040
        window.location = path_join(app_url('diff'), current_path, selected_files[0] || '');
829 by wagrant
Add an svndiff action, and give it an option in the action listbox.
1041
        break;
918 by wagrant
browser: Expose svn update functionality. This brings a need for an
1042
    case "svnupdate":
1043
        action_update(selected_files);
1044
        break;
919 by wagrant
fileservice_lib: Implement "svn resolved".
1045
    case "svnresolved":
1046
        action_resolved(selected_files);
1047
        break;
607 by mattgiuca
browser/browser.js: All the actions in "more actions" now actually take
1048
    case "svncommit":
1049
        action_commit(selected_files);
1050
        break;
832 by wagrant
Add svnlog to the file actions dropdown.
1051
    case "svnlog":
1661 by Matt Giuca
browser.js: Fixed generation of links in file browser to Serve, Download and Share-this-file links containing special URI characters. Now properly URL-encoded. Added util.js app_url and public_app_url, replacing calls to app_path and public_app_path. Fixes Launchpad bug #524176.
1052
        window.location = path_join(app_url('svnlog'), current_path, selected_files[0] || '');
832 by wagrant
Add svnlog to the file actions dropdown.
1053
        break;
1086 by chadnickbok
This commit fixes issue #10 and part of issue #9
1054
    case "svncopy":
1055
        action_svncopy(selected_files);
1056
        break;
1057
    case "svncut":
1058
        action_svncut(selected_files);
1059
        break;
1318.1.2 by David Coles
Add Subversion Cleanup to web UI
1060
    case "svncleanup":
1061
        action_svncleanup(".");
1062
        break;
607 by mattgiuca
browser/browser.js: All the actions in "more actions" now actually take
1063
    }
597 by mattgiuca
Major refactor of actions in File browser.
1064
}
1065
713 by dcoles
browser: Added console and run button to allow Python files to be executed in
1066
/** User clicks "Run" button.
1067
 * Do an Ajax call and print the test output.
1068
 */
1069
function runfile(localpath)
1070
{
865 by wagrant
browser: Warn users before running, serving and refreshing if the file
1071
    if (!maybe_save('The last saved version will be run.')) return false;
1072
713 by dcoles
browser: Added console and run button to allow Python files to be executed in
1073
    /* Dump the entire file to the console */
1074
    var callback = function()
1075
    {
1076
        console_enter_line("execfile('" + localpath + "')", "block");
1077
    }
1078
    start_server(callback)
1079
    return;
1080
}
1081
170 by mattgiuca
browser: Added CSS and JS files (not much in them).
1082
/** Called when the page loads initially.
1083
 */
849 by dcoles
Browser: Ported Browser to the new scripts_init framework. Started to decouple
1084
function browser_init()
170 by mattgiuca
browser: Added CSS and JS files (not much in them).
1085
{
188 by mattgiuca
browser.js: Can now (shakily) handle directory listings. (lots of code!)
1086
    /* Navigate (internally) to the path in the URL bar.
1087
     * This causes the page to be populated with whatever is at that address,
1088
     * whether it be a directory or a file.
1089
     */
1326.1.2 by David Coles
Small refactor of browser's JavaScript to allow do_action to be called from
1090
    var path = get_path();
1091
    navigate(path);
1092
}
1093
1339 by William Grant
Revert client-side parts of r1333; reliance on the deprecated tab mechanism is to be avoided.
1094
/** Gets the current path of the window */
1095
function get_path() {
1096
    var path = parse_url(window.location.href).path;
1097
    /* Strip out root_dir + "/files" from the front of the path */
1098
    var strip = make_path(this_app);
1099
    if (path.substr(0, strip.length) == strip)
1100
        path = path.substr(strip.length+1);
1101
    else
1102
    {
1103
        /* See if this is an edit path */
1104
        strip = make_path(edit_app);
1105
        if (path.substr(0, strip.length) == strip)
1106
        {
1107
            path = path.substr(strip.length+1);
1108
        }
1109
    }
1110
1111
    if (path.length == 0)
1112
    {
1113
        /* Navigate to the user's home directory by default */
1114
        /* TEMP? */
1115
        path = username;
1116
    }
1117
1118
    return path;
1119
}