Explorar o código

Merge pull request #38 from AToMPM/refactor-file-browser2

Move file browser into separate class.
BentleyJOakes %!s(int64=7) %!d(string=hai) anos
pai
achega
235f365db0
Modificáronse 4 ficheiros con 427 adicións e 422 borrados
  1. 1 0
      client/atompm.html
  2. 422 0
      client/file_browser.js
  3. 1 192
      client/gui_utils.js
  4. 3 230
      client/window_management.js

+ 1 - 0
client/atompm.html

@@ -41,6 +41,7 @@
 		<script text="text/javascript" src="client/geometry_utils.js"></script>
 		<script text="text/javascript" src="client/connection_utils.js"></script>
 		<script text="text/javascript" src="client/window_management.js"></script>
+		<script text="text/javascript" src="client/file_browser.js"></script>
 		<script text="text/javascript" src="client/query_response.js"></script>
 		<script text="text/javascript" src="client/collaboration.js"></script>
 		<script text="text/javascript" src="client/layout.js"></script>

+ 422 - 0
client/file_browser.js

@@ -0,0 +1,422 @@
+class FileBrowser{
+
+    static buildFileBrowser(extensions, manualInput, title, startDir, callback) {
+        HttpUtils.httpReq(
+            'GET',
+            HttpUtils.url('/filelist', __NO_WID),
+            undefined,
+            function (statusCode, resp) {
+                extensions.push('/');
+                var fnames = __localizeFilenames(
+                    __filterFilenamesByExtension(
+                        resp.split('\n'),
+                        extensions || ['.*'])
+                    ).sort(),
+                    folder_buttons = $('<div>'),
+                    new_folder_b = $('<button>'),
+                    rename_folder_b = $('<button>'),
+                    delete_folder_b = $('<button>'),
+                    move_folder_b = $('<button>'),
+                    file_buttons = $('<div>'),
+                    rename_file_b = $('<button>'),
+                    delete_file_b = $('<button>'),
+                    move_file_b = $('<button>'),
+                    feedbackarea = $('<div>'),
+                    feedback = GUIUtils.getTextSpan('', "feedback"),
+                    fileb =
+                        FileBrowser.getFileBrowser(fnames, false, manualInput, __getRecentDir(startDir));
+
+                new_folder_b.html('new folder')
+                    .click(function (ev) {
+                        var folder_name = prompt("please fill in a name for the folder");
+                        if (folder_name != null) {
+                            folder_name = folder_name.replace(/^\s+|\s+$/g, ''); // trim
+                            if (!folder_name.match(/^[a-zA-Z0-9_\s]+$/i)) {
+                                feedback.html("invalid folder name: " + folder_name);
+                            } else {
+                                console.log("/" + window.localStorage.getItem('user') + fileb['getcurrfolder']() + folder_name + '.folder');
+                                DataUtils.createFolder("/" + window.localStorage.getItem('user') + fileb['getcurrfolder']() + folder_name + '.folder', function (statusCode, resp) {
+                                    if (!utils.isHttpSuccessCode(statusCode)) {
+                                        feedback.html(resp)
+                                    } else {
+                                        feedback.html('created ' + folder_name);
+                                        fnames.push(fileb['getcurrfolder']() + folder_name + "/")
+                                        fileb['refresh'](fnames);
+                                    }
+                                });
+                            }
+                        }
+                    });
+                folder_buttons.append(new_folder_b);
+
+                rename_folder_b.html('rename folder')
+                    .click(function (ev) {
+                        var value = fileb['getcurrfolder']();
+                        var folder_name = prompt("please fill in a new name for folder " + value);
+                        if (folder_name != null) {
+                            folder_name = folder_name.replace(/^\s+|\s+$/g, ''); // trim
+                            if (!folder_name.match(/^[a-zA-Z0-9_\s]+$/i)) {
+                                feedback.html("invalid folder name: " + folder_name);
+                            } else {
+                                DataUtils.renameInCloud("/" + window.localStorage.getItem('user') + value.slice(0, -1) + ".folder", folder_name, function (statusCode, resp) {
+                                    if (!utils.isHttpSuccessCode(statusCode)) {
+                                        feedback.html(resp);
+                                    } else {
+                                        var matches = value.match(/^\/(.*\/)?(.*)\/$/),
+                                            newvalue = "/" + (matches[1] || "") + folder_name + "/";
+                                        for (var idx in fnames) {
+                                            fnames[idx] = fnames[idx].replace(new RegExp("^(" + value + ")(.*)"), newvalue + "$2");
+                                        }
+                                        fileb['refresh'](fnames, newvalue);
+                                        fileb['clearselection']();
+                                        feedback.html('renamed ' + value + ' to ' + newvalue);
+                                    }
+                                });
+                            }
+                        }
+                    });
+                folder_buttons.append(rename_folder_b);
+
+                delete_folder_b.html('delete folder')
+                    .click(function (ev) {
+                        var value = fileb['getcurrfolder']();
+                        if (confirm("are you sure you want to delete " + value + "?")) {
+                            DataUtils.deleteFromCloud("/" + window.localStorage.getItem('user') + value.slice(0, -1) + ".folder", function (statusCode, resp) {
+                                if (!utils.isHttpSuccessCode(statusCode)) {
+                                    feedback.html(resp);
+                                } else {
+                                    var matches = value.match(/^\/(.*\/)?(.*)\/$/),
+                                        newvalue = "/_Trash_" + value;
+                                    for (var idx in fnames) {
+                                        fnames[idx] = fnames[idx].replace(new RegExp("^(" + value + ")(.*)"), newvalue + "$2");
+                                    }
+                                    fileb['refresh'](fnames);
+                                    fileb['clearselection']();
+                                    feedback.html('deleted ' + value);
+                                }
+                            });
+                        }
+                    });
+                folder_buttons.append(delete_folder_b);
+
+                move_folder_b.html('move folder')
+                    .click(function (ev) {
+                        var value = fileb['getcurrfolder']();
+                        var folder_loc = prompt("please fill in a new parent folder for folder " + value);
+                        if (folder_loc != null) {
+                            folder_loc = folder_loc.replace(/^\s+|\s+$/g, ''); // trim
+                            if (!folder_loc.match(/^\/([a-zA-Z0-9_\s]+\/)*$/i)) {
+                                feedback.html("invalid parent location: " + folder_loc);
+                            } else {
+                                DataUtils.moveInCloud("/" + window.localStorage.getItem('user') + value.slice(0, -1) + ".folder", folder_loc, function (statusCode, resp) {
+                                    if (!utils.isHttpSuccessCode(statusCode)) {
+                                        feedback.html(resp);
+                                    } else {
+                                        var matches = value.match(/^\/(.*\/)?(.*)\/$/),
+                                            newvalue = folder_loc + matches[2] + "/";
+                                        for (var idx in fnames) {
+                                            fnames[idx] = fnames[idx].replace(new RegExp("^(" + value + ")(.*)"), newvalue + "$2");
+                                        }
+                                        fileb['refresh'](fnames, newvalue);
+                                        fileb['clearselection']();
+                                        feedback.html('moved ' + value + ' to ' + folder_loc);
+                                    }
+                                });
+                            }
+                        }
+                    });
+                folder_buttons.append(move_folder_b);
+
+                rename_file_b.html('rename file')
+                    .click(function (ev) {
+                        var value = fileb['getselection']();
+                        var file_name = prompt("please fill in a new name for file " + value);
+                        if (file_name != null) {
+                            file_name = file_name.replace(/^\s+|\s+$/g, ''); // trim
+                            if (!file_name.match(/^[a-zA-Z0-9_\s\.]+$/i)) {
+                                feedback.html("invalid file name: " + file_name);
+                            } else {
+                                DataUtils.renameInCloud("/" + window.localStorage.getItem('user') + value + ".file", file_name, function (statusCode, resp) {
+                                    if (!utils.isHttpSuccessCode(statusCode)) {
+                                        feedback.html(resp);
+                                    } else {
+                                        var matches = value.match(/^\/(.*\/)?(.*)$/),
+                                            newvalue = "/" + (matches[1] || "") + file_name;
+                                        var idx = fnames.indexOf(value);
+                                        if (idx >= 0) {
+                                            fnames[idx] = newvalue;
+                                        }
+                                        fileb['refresh'](fnames);
+                                        fileb['clearselection']();
+                                        feedback.html('renamed ' + value + ' to ' + newvalue);
+                                    }
+                                });
+                            }
+                        }
+                    });
+                file_buttons.append(rename_file_b);
+
+                delete_file_b.html('delete file')
+                    .click(function (ev) {
+                        var value = fileb['getselection']();
+                        if (confirm("are you sure you want to delete " + value + "?")) {
+                            DataUtils.deleteFromCloud("/" + window.localStorage.getItem('user') + value + ".file", function (statusCode, resp) {
+                                if (!utils.isHttpSuccessCode(statusCode)) {
+                                    feedback.html(resp);
+                                } else {
+                                    feedback.html('deleted ' + value);
+                                    var idx = fnames.indexOf(value);
+                                    if (idx >= 0) {
+                                        fnames.splice(idx, 1);
+                                    }
+                                    fileb['refresh'](fnames);
+                                    fileb['clearselection']();
+                                }
+                            });
+                        }
+                    });
+                file_buttons.append(delete_file_b);
+
+                move_file_b.html('move file')
+                    .click(function (ev) {
+                        var value = fileb['getselection']();
+                        var folder_loc = prompt("please fill in a new parent folder for file " + value);
+                        if (folder_loc != null) {
+                            folder_loc = folder_loc.replace(/^\s+|\s+$/g, ''); // trim
+                            if (!folder_loc.match(/^\/([a-zA-Z0-9_\s]+\/)*$/i)) {
+                                feedback.html("invalid parent location: " + folder_loc);
+                            } else {
+                                DataUtils.moveInCloud("/" + window.localStorage.getItem('user') + value + ".file", folder_loc, function (statusCode, resp) {
+                                    if (!utils.isHttpSuccessCode(statusCode)) {
+                                        feedback.html(resp);
+                                    } else {
+                                        var matches = value.match(/^\/(.*\/)?(.*)$/),
+                                            newvalue = folder_loc + matches[2];
+                                        feedback.html('moved ' + value + ' to ' + folder_loc);
+                                        var idx = fnames.indexOf(value);
+                                        if (idx >= 0) {
+                                            fnames[idx] = newvalue;
+                                        }
+                                        fileb['refresh'](fnames);
+                                        fileb['clearselection']();
+                                    }
+                                });
+                            }
+                        }
+                    });
+                file_buttons.append(move_file_b);
+
+                GUIUtils.setupAndShowDialog(
+                    [fileb['filebrowser'], folder_buttons, file_buttons, feedback],
+                    function () {
+                        var value = [fileb['getselection']()];
+                        if (value.length > 0 && value[0] != "" && startDir) {
+                            __setRecentDir(startDir, value[0].substring(0, value[0].lastIndexOf('/') + 1));
+                        }
+                        return value;
+                    },
+                    __TWO_BUTTONS,
+                    title,
+                    callback);
+            });
+    };
+
+
+    /**
+     * Returns a <div> with an interactive file browser within it
+     *
+     * @param fnames - a complete list of all files in the directory tree
+     * structure
+     * @param draggable - when true, files and folders can be meaningfully
+     * dragged
+     * @param newfile when true, an editable new file icon is present
+     * @param startfolder if set, starts navigation at the specified folder
+     */
+    static getFileBrowser(fnames, draggable, newfile, startfolder) {
+        var maxFnameLength = utils.max(fnames, function (_) {
+                return _.length;
+            }),
+            fileb = $("<div>"),
+            navdiv = $("<div>"),
+            input = $("<input>"),
+            selection = undefined,
+            currfolder = '/',
+            clearSelection =
+                function () {
+                    if (selection) {
+                        selection.attr("class", 'fileb_icon');
+                        selection = undefined;
+                        input.val('');
+                    }
+                },
+            navbuttononclick =
+                /* 1 construct the full path associated to the clicked button
+                    2 remove 'deeper' buttons
+                    3 chdir to selected folder */
+                function (ev) {
+                    var path = '';
+                    for (var i = 0; i < navdiv.children("button").length; i++) {
+                        path += $(navdiv.children()[i]).html() + '/';
+                        if ($(navdiv.children()[i]).html() == $(ev.target).html())
+                            break;
+                    }
+
+                    setCurrentFileBrowserFolder(path.substring(1), fnames);
+                },
+            setCurrentFileBrowserFolder =
+                /* 1 determine files and folders from the given folder
+                    2 produce icons for them and add them to to-be content div
+                    3 create navigation toolbar for complete directory hierarchy
+                    4 replace previous content div, if any, with new one
+                      5 clear past selection, if any, and remember current folder */
+                function (folder, fnames) {
+                    var div = $('#div_fileb-contents'),
+                        folders = [],
+                        files = [],
+                        maxFnameLength = 0,
+                        exists = false;
+
+                    // If it already exists, remove everything!
+                    if (div.length > 0) {
+                        $('#div_fileb-contents').remove();
+                        //					 exists = true;
+                    }
+
+                    div = $("<div>");
+
+                    div.attr("class", 'fileb_pane')
+                        .attr("id", 'div_fileb-contents');
+
+                    fnames.forEach(function (fname) {
+                        let _folder = utils.regexpe(folder);
+                        let matches = fname.match('^' + _folder + '(.+?/)');
+                        if (matches) {
+                            if (!utils.contains(folders, matches[1]))
+                                folders.push(matches[1]);
+                            else
+                                return;
+                        }
+                        else if ((matches = fname.match('^' + _folder + '(.*)'))) {
+                            if (matches[1].length > 0) {
+                                files.push(matches[1]);
+                            } else {
+                                return;
+                            }
+                        }
+                        else
+                            return;
+
+                        maxFnameLength =
+                            Math.max(maxFnameLength, matches[1].length);
+                    });
+
+                    //				 var tmpDiv = $("<div>");
+                    folders.concat(files).forEach(function (fname) {
+                        let icon = HttpUtils.getFileIcon(fname);
+                        if (icon) {
+                            icon.css("width", 8 + maxFnameLength + 'ex');
+                            icon.click(function (ev) {
+                                clearSelection();
+
+                                if (fname.match(/\/$/))
+                                    setCurrentFileBrowserFolder(folder + fname, fnames);
+                                else {
+                                    input.val(folder + fname);
+                                    selection = icon;
+                                    selection.attr("class", 'fileb_icon_selected');
+                                }
+                            });
+
+                            if (draggable) {
+                                //icon.setAttribute('draggable',true);
+                                icon.attr("draggable", true);
+                                icon.get(0).ondragstart =
+                                    function (event) {
+                                        var uri = HttpUtils.url(folder + fname + '.file', __NO_WID);
+                                        event.dataTransfer.effectAllowed = 'copyMove';
+                                        event.dataTransfer.setData(
+                                            'DownloadURL',
+                                            'application/zip:' + fname + '.zip:' +
+                                            window.location.origin + uri);
+                                        event.dataTransfer.setData('uri', uri);
+                                    };
+                            }
+
+                            div.append(icon);
+                        }
+                    });
+
+                    if (newfile) {
+                        var icon = HttpUtils.getNewFileIcon(function (ev) {
+                            input.val(folder + ev.target.textContent);
+                        });
+                        icon.css("width", 8 + maxFnameLength + 'ex');
+                        div.append(icon);
+                    }
+
+                    navdiv.empty();
+
+                    //				 while (navdiv.children().length > 0) {
+                    //					navdiv.find(navdiv.lastChild).remove();
+                    //				 }
+                    //let tmpDiv = $("<div>");
+                    var subfolders = folder.split('/').filter(function (subf) {
+                        return subf != '';
+                    });
+                    subfolders.unshift('/');
+                    subfolders.forEach(function (subfolder) {
+                        var navbutton = $('<button>');
+                        navbutton.html(subfolder);
+                        navbutton.click(navbuttononclick);
+                        navdiv.append(navbutton);
+                    });
+
+                    //navdiv.html( tmpDiv.html() );
+
+
+                    if (exists) {
+                        //					 $('#div_fileb-contents').html( div.html() );
+                        //					 fileb.append(div);
+                        $('#div_fileb-contents').remove();
+                        fileb.append(div);
+                    } else
+                        fileb.append(div);
+
+                    clearSelection();
+                    currfolder = folder;
+                };
+
+        fileb.css("width", maxFnameLength + 'ex')
+            .css("maxWidth", '100%');
+
+        navdiv.css("align", 'left');
+
+        input.attr("type", 'hidden');
+
+        fileb.append(navdiv);
+        fileb.append(input);
+
+        setCurrentFileBrowserFolder(startfolder ? startfolder : '/', fnames);
+
+        return {
+            'filebrowser': fileb,
+            'filepane': function () {
+                return $('#div_fileb-contents');
+            },
+            'getcurrfolder': function () {
+                return currfolder;
+            },
+            'getselection': function () {
+                return input.val();
+            },
+            'clearselection': function () {
+                clearSelection()
+            },
+            'refresh': function (fnames, the_folder) {
+                setCurrentFileBrowserFolder(the_folder || currfolder, fnames);
+            }
+        };
+    };
+
+
+}

+ 1 - 192
client/gui_utils.js

@@ -49,198 +49,7 @@ GUIUtils = function(){
 		cb.prop("checked", checked);
 		return cb;
 	};
-	
-	/**
-	 * Returns a <div> with an interactive file browser within it
-	 * 
-	 * @param fnames - a complete list of all files in the directory tree
-	 * structure
-	 * @param draggable - when true, files and folders can be meaningfully
-	 * dragged
-	 * @param newfile when true, an editable new file icon is present
-	 * @param startfolder if set, starts navigation at the specified folder
-	 */
-	this.getFileBrowser = function(fnames, draggable, newfile, startfolder){
-		var maxFnameLength = utils.max(fnames,function(_) {return _.length;}),
-			 fileb = $("<div>"),
-			 navdiv = $("<div>"),
-			 input = $("<input>"),
-			 selection = undefined,
-			 currfolder = '/',
-			 clearSelection = 
-				 function()
-				 {
-					 if( selection )
-					 {
-						 selection.attr("class", 'fileb_icon');
-						 selection = undefined;
-						 input.val('');
-					 }
-				 },
-			 navbuttononclick	=
-				 /* 1 construct the full path associated to the clicked button
-					 2 remove 'deeper' buttons
-					 3 chdir to selected folder */
-				 function(ev)
-				 {
-					 var path = '';
-					 for( var i=0; i<navdiv.children("button").length; i++ )
-					 {
-						 path += $(navdiv.children()[i]).html() +'/';
-						 if( $(navdiv.children()[i]).html() == $(ev.target).html() )
-							 break;
-					 }
-					 
-					 setCurrentFileBrowserFolder(path.substring(1), fnames);
-				 },
-			 setCurrentFileBrowserFolder = 
-				 /* 1 determine files and folders from the given folder
-					 2 produce icons for them and add them to to-be content div
-					 3 create navigation toolbar for complete directory hierarchy
-					 4 replace previous content div, if any, with new one 
-				  	 5 clear past selection, if any, and remember current folder */
-				 function(folder,fnames) 
-				 {
-					 var div = $('#div_fileb-contents'),
-						  folders		  = [],
-						  files			  = [],
-						  maxFnameLength = 0,
-						  exists = false;
-					 
-					 // If it already exists, remove everything!
-					 if( div.length > 0 ) {
-						 $('#div_fileb-contents').remove();
-	//					 exists = true;
-					 }
-					 
-					 div = $("<div>");
-						 
-					 div.attr("class", 'fileb_pane')
-					 	.attr("id", 'div_fileb-contents');
-					 
-					 fnames.forEach( function(fname) {
-						 var _folder = utils.regexpe(folder);
-						 if( (matches=fname.match('^'+_folder+'(.+?/)')) )
-						 {
-							 if( ! utils.contains(folders,matches[1]) )
-								 folders.push(matches[1]);
-							 else
-								 return;
-						 }
-						 else if( (matches=fname.match('^'+_folder+'(.*)')) ) {
-                             if (matches[1].length > 0) {
-                                 files.push(matches[1]);
-                             } else {
-                                 return;
-                             }
-                         }
-						 else
-							 return;
-							 
-						 maxFnameLength = 
-							 Math.max(maxFnameLength,matches[1].length);
-					 });
-							 
-	//				 var tmpDiv = $("<div>");
-					 folders.concat(files).forEach( function(fname) {
-						 var icon = HttpUtils.getFileIcon(fname);
-						 if( icon )
-						 {
-							 icon.css("width", 8+maxFnameLength+'ex');
-							 icon.click( function(ev) {
-							 	 clearSelection();								 	
-	
-								 if( fname.match(/\/$/) )
-									 setCurrentFileBrowserFolder(folder+fname,fnames);
-								 else
-								 {
-									 input.val( folder+fname );
-									 selection = icon;
-									 selection.attr("class", 'fileb_icon_selected');
-								 }
-							 });
-				 			 
-				 			 if( draggable )
-							 {
-								 //icon.setAttribute('draggable',true);
-				 				 icon.attr("draggable", true);
-								 icon.get(0).ondragstart = 
-									 function(event) 
-									 {
-										 var uri = HttpUtils.url(folder+fname+'.file',__NO_WID);
-			  							 event.dataTransfer.effectAllowed = 'copyMove';
-			  							 event.dataTransfer.setData(
-											 'DownloadURL', 
-											 'application/zip:'+fname+'.zip:'+
-												 window.location.origin+uri);
-										 event.dataTransfer.setData('uri',uri);
-									 };
-							 }
-	
-							 div.append(icon);
-						 }
-					 });
-					 
-					 if( newfile )
-					 {
-						 var icon = HttpUtils.getNewFileIcon( function(ev) {
-							 input.val( folder+ev.target.textContent );
-						 });
-						 icon.css("width", 8+maxFnameLength+'ex');
-						 div.append(icon);
-					 }
-					 
-					 navdiv.empty();
-					 
-	//				 while (navdiv.children().length > 0) {
-	//					navdiv.find(navdiv.lastChild).remove();
-	//				 }
-					 tmpDiv = $("<div>");
-					 var subfolders = folder.split('/').filter(function(subf) {return subf != '';});
-					 subfolders.unshift('/');
-					 subfolders.forEach(function(subfolder) {
-						var navbutton = $('<button>');
-						navbutton.html( subfolder );
-						navbutton.click(navbuttononclick);
-						navdiv.append(navbutton);
-					 });
-					 
-					 //navdiv.html( tmpDiv.html() );
-					 
-					 
-					 if( exists ) {
-	//					 $('#div_fileb-contents').html( div.html() );
-	//					 fileb.append(div);
-						 $('#div_fileb-contents').remove();
-						 fileb.append(div);
-					 } else
-						 fileb.append(div);
-	
-					 clearSelection();				 
-					 currfolder = folder;
-				 };
-	
-		fileb.css("width", maxFnameLength+'ex')
-			.css("maxWidth", '100%');
-		
-		navdiv.css("align",  'left');
-		
-		input.attr("type", 'hidden');
-		
-		fileb.append(navdiv);
-		fileb.append(input);
-		
-		setCurrentFileBrowserFolder(startfolder ? startfolder : '/',fnames);
-	
-		return {'filebrowser':	 fileb,
-				  'filepane':	 	 function() {return $('#div_fileb-contents');},
-				  'getcurrfolder': function() {return currfolder;},	
-				  'getselection':	 function()	{return input.val();},
-                  'clearselection': function() {clearSelection()},
-                  'refresh': function(fnames, the_folder) {
-                      setCurrentFileBrowserFolder(the_folder || currfolder, fnames);
-                  }};
-	};
+
 	
 	// TODO: replace the bundled function with an actual object generation. The
 	// current method is sloppy.

+ 3 - 230
client/window_management.js

@@ -99,7 +99,7 @@ WindowManagement = function(){
 										return _.length;
 									}),
 						 
-								fileb 			= GUIUtils.getFileBrowser(fnames,true),
+								fileb 			= FileBrowser.getFileBrowser(fnames,true),
 								feedbackarea	= $('<div>'),
 								feedback		 = GUIUtils.getTextSpan(''),
 								progressbar	 = $('<div>'),
@@ -392,236 +392,9 @@ WindowManagement = function(){
 			error(args,true);
 	
 		else if( type == _FILE_BROWSER )
-			/* args: extensions,multipleChoice,manualInput,title,startDir */
+			/* args: extensions,manualInput,title,startDir */
 		{
-			HttpUtils.httpReq(
-				'GET',
-				HttpUtils.url('/filelist',__NO_WID),
-				undefined,
-				function(statusCode,resp)
-				{
-                    args['extensions'].push('/');
-					var fnames = __localizeFilenames(
-							__filterFilenamesByExtension(
-								resp.split('\n'),
-								args['extensions'] || ['.*'])
-							).sort(),
-							maxFnameLength = 
-								utils.max(fnames,function(_) {return _.length;}),
-                             folder_buttons = $('<div>'),
-                             new_folder_b = $('<button>'),
-                             rename_folder_b = $('<button>'),
-                             delete_folder_b = $('<button>'),
-                             move_folder_b = $('<button>'),
-                             file_buttons = $('<div>'),
-                             rename_file_b = $('<button>'),
-                             delete_file_b = $('<button>'),
-                             move_file_b = $('<button>'),                
-                             feedbackarea = $('<div>'),
-                             feedback = GUIUtils.getTextSpan('',"feedback"),
-							 fileb = 
-								 GUIUtils.getFileBrowser(fnames,false,args['manualInput'],__getRecentDir(args['startDir']));
-                    
-                    new_folder_b.html('new folder')
-                    .click(function(ev) {
-                        var folder_name = prompt("please fill in a name for the folder");
-                        if (folder_name != null) {
-                            folder_name = folder_name.replace(/^\s+|\s+$/g, ''); // trim
-                            if (!folder_name.match(/^[a-zA-Z0-9_\s]+$/i)) {
-                                feedback.html("invalid folder name: " + folder_name);
-                            } else {
-                                console.log("/" + window.localStorage.getItem('user') + fileb['getcurrfolder']() + folder_name + '.folder');
-                                DataUtils.createFolder("/" + window.localStorage.getItem('user') + fileb['getcurrfolder']() + folder_name + '.folder', function(statusCode, resp) {
-                                    if( ! utils.isHttpSuccessCode(statusCode) ) {
-                                        feedback.html(resp)
-                                    } else {
-                                        feedback.html('created ' + folder_name);
-                                        fnames.push(fileb['getcurrfolder']() + folder_name + "/")
-                                        fileb['refresh'](fnames);
-                                    }
-                                });
-                            }
-                        }
-                    });
-                    folder_buttons.append(new_folder_b);
-                    
-                    rename_folder_b.html('rename folder')
-                    .click(function(ev) {
-                        var value = fileb['getcurrfolder']();
-                        var folder_name = prompt("please fill in a new name for folder " + value);
-                        if (folder_name != null) {
-                            folder_name = folder_name.replace(/^\s+|\s+$/g, ''); // trim
-                            if (!folder_name.match(/^[a-zA-Z0-9_\s]+$/i)) {
-                                feedback.html("invalid folder name: " + folder_name);
-                            } else {
-                                DataUtils.renameInCloud("/" + window.localStorage.getItem('user') + value.slice(0, -1) + ".folder", folder_name, function(statusCode,resp)
-                                    {
-                                        if( ! utils.isHttpSuccessCode(statusCode) ) {
-                                            feedback.html(resp);
-                                        } else {
-                                            var matches = value.match(/^\/(.*\/)?(.*)\/$/),
-                                                newvalue = "/" + (matches[1] || "") + folder_name + "/";
-                                            for (var idx in fnames) {
-                                                fnames[idx] = fnames[idx].replace(new RegExp("^("+value+")(.*)"), newvalue+"$2"); 
-                                            }
-                                            fileb['refresh'](fnames, newvalue);
-                                            fileb['clearselection']();
-                                            feedback.html('renamed ' + value + ' to ' + newvalue);
-                                        }
-                                    });
-                            }
-                        }
-                    });
-                    folder_buttons.append(rename_folder_b);
-                    
-                    delete_folder_b.html('delete folder')
-                    .click(function(ev) {
-                        var value = fileb['getcurrfolder']();
-                        if (confirm("are you sure you want to delete " + value + "?")) {
-                            DataUtils.deleteFromCloud("/" + window.localStorage.getItem('user') + value.slice(0, -1) + ".folder", function(statusCode,resp)
-                                {
-                                    if( ! utils.isHttpSuccessCode(statusCode) ) {
-                                        feedback.html(resp);
-                                    } else {
-                                        var matches = value.match(/^\/(.*\/)?(.*)\/$/),
-                                            newvalue = "/_Trash_" + value;
-                                        for (var idx in fnames) {
-                                            fnames[idx] = fnames[idx].replace(new RegExp("^("+value+")(.*)"), newvalue+"$2");
-                                        }
-                                        fileb['refresh'](fnames);
-                                        fileb['clearselection']();
-                                        feedback.html('deleted ' + value);
-                                    }
-                                });
-                        }
-                    });
-                    folder_buttons.append(delete_folder_b);
-                    
-                    move_folder_b.html('move folder')
-                    .click(function(ev) {
-                        var value = fileb['getcurrfolder']();
-                        var folder_loc = prompt("please fill in a new parent folder for folder " + value);
-                        if (folder_loc != null) {
-                            folder_loc = folder_loc.replace(/^\s+|\s+$/g, ''); // trim
-                            if (!folder_loc.match(/^\/([a-zA-Z0-9_\s]+\/)*$/i)) {
-                                feedback.html("invalid parent location: " + folder_loc);
-                            } else {
-                                DataUtils.moveInCloud("/" + window.localStorage.getItem('user') + value.slice(0, -1) + ".folder", folder_loc, function(statusCode,resp)
-                                    {
-                                        if( ! utils.isHttpSuccessCode(statusCode) ) {
-                                            feedback.html(resp);
-                                        } else {
-                                            var matches = value.match(/^\/(.*\/)?(.*)\/$/),
-                                                newvalue = folder_loc + matches[2] + "/";
-                                            for (var idx in fnames) {
-                                                fnames[idx] = fnames[idx].replace(new RegExp("^("+value+")(.*)"), newvalue+"$2"); 
-                                            }
-                                            fileb['refresh'](fnames, newvalue);
-                                            fileb['clearselection']();
-                                            feedback.html('moved ' + value + ' to ' + folder_loc);
-                                        }
-                                    });
-                            }
-                        }
-                    });
-                    folder_buttons.append(move_folder_b);
-                    
-                    rename_file_b.html('rename file')
-                    .click(function(ev) {
-                        var value = fileb['getselection']();
-                        var file_name = prompt("please fill in a new name for file " + value);
-                        if (file_name != null) {
-                            file_name = file_name.replace(/^\s+|\s+$/g, ''); // trim
-                            if (!file_name.match(/^[a-zA-Z0-9_\s\.]+$/i)) {
-                                feedback.html("invalid file name: " + file_name);
-                            } else {
-                                DataUtils.renameInCloud("/" + window.localStorage.getItem('user') + value + ".file", file_name, function(statusCode,resp)
-                                    {
-                                        if( ! utils.isHttpSuccessCode(statusCode) ) {
-                                            feedback.html(resp);
-                                        } else {
-                                            var matches = value.match(/^\/(.*\/)?(.*)$/),
-                                                newvalue = "/" + (matches[1] || "") + file_name;
-                                            var idx = fnames.indexOf(value);
-                                            if (idx >= 0) {
-                                                fnames[idx] = newvalue;
-                                            }
-                                            fileb['refresh'](fnames);
-                                            fileb['clearselection']();
-                                            feedback.html('renamed ' + value + ' to ' + newvalue);
-                                        }
-                                    });
-                            }
-                        }
-                    });
-                    file_buttons.append(rename_file_b);
-                    
-                    delete_file_b.html('delete file')
-                    .click(function(ev) {
-                        var value = fileb['getselection']();
-                        if (confirm("are you sure you want to delete " + value + "?")) {
-                            DataUtils.deleteFromCloud("/" + window.localStorage.getItem('user') + value + ".file", function(statusCode,resp)
-                                {
-                                    if( ! utils.isHttpSuccessCode(statusCode) ) {
-                                        feedback.html(resp);
-                                    } else {
-                                        feedback.html('deleted ' + value);
-                                        var idx = fnames.indexOf(value);
-                                        if (idx >= 0) {
-                                            fnames.splice(idx, 1);
-                                        }
-                                        fileb['refresh'](fnames);
-                                        fileb['clearselection']();
-                                    }
-                                });
-                        }
-                    });
-                    file_buttons.append(delete_file_b);                    
-                    
-                    move_file_b.html('move file')
-                    .click(function(ev) {
-                        var value = fileb['getselection']();
-                        var folder_loc = prompt("please fill in a new parent folder for file " + value);
-                        if (folder_loc != null) {
-                            folder_loc = folder_loc.replace(/^\s+|\s+$/g, ''); // trim
-                            if (!folder_loc.match(/^\/([a-zA-Z0-9_\s]+\/)*$/i)) {
-                                feedback.html("invalid parent location: " + folder_loc);
-                            } else {
-                                DataUtils.moveInCloud("/" + window.localStorage.getItem('user') + value + ".file", folder_loc, function(statusCode,resp)
-                                    {
-                                        if( ! utils.isHttpSuccessCode(statusCode) ) {
-                                            feedback.html(resp);
-                                        } else {
-                                            var matches = value.match(/^\/(.*\/)?(.*)$/),
-                                                newvalue = folder_loc + matches[2];
-                                            feedback.html('moved ' + value + ' to ' + folder_loc);
-                                            var idx = fnames.indexOf(value);
-                                            if (idx >= 0) {
-                                                fnames[idx] = newvalue;
-                                            }
-                                            fileb['refresh'](fnames);
-                                            fileb['clearselection']();
-                                        }
-                                    });
-                            }
-                        }
-                    });
-                    file_buttons.append(move_file_b);
-	
-					GUIUtils.setupAndShowDialog(
-						[fileb['filebrowser'],folder_buttons,file_buttons,feedback],
-						function() 
-						{
-							var value = [fileb['getselection']()];
-							if (value.length > 0 && value[0] != "" && args['startDir']) {
-								__setRecentDir(args['startDir'],value[0].substring(0, value[0].lastIndexOf('/') + 1));
-							}
-							return value;
-						},
-						__TWO_BUTTONS,
-						args['title'],
-						callback);
-				});	
+			FileBrowser.buildFileBrowser(args['extensions'], args['manualInput'], args['title'], args['startDir'], callback);
 		}
 	
 		else if( type == _LEGAL_CONNECTIONS )