/*---------------------------------------------------------
Setup, Layout, and Status Functions
---------------------------------------------------------*/
// Sets paths to connectors based on language selection.
var treeConnector = 'scripts/jquery.filetree/connectors/jqueryFileTree.' + lang;
var fileConnector = 'connectors/' + lang + '/filemanager.' + lang;
// function to retrieve GET params
$.urlParam = function(name){
var results = new RegExp('[\\?&]' + name + '=([^]*)').exec(window.location.href);
return results[1] || 0;
}
// Get localized messages from file
// through culture var or from URL
if($.urlParam('langCode') != 0 && file_exists ('scripts/languages/' + $.urlParam('langCode') + '.js')) culture = $.urlParam('langCode');
var lg = [];
$.ajax({
url: 'scripts/languages/' + culture + '.js',
async: false,
dataType: 'json',
success: function (json) {
lg = json;
}
});
// Options for alert, prompt, and confirm dialogues.
$.SetImpromptuDefaults({
overlayspeed: 'fast',
show: 'fadeIn',
opacity: 0.4
});
// Forces columns to fill the layout vertically.
// Called on initial page load and on resize.
var setDimensions = function(){
var newH = $(window).height() - 50;
$('#splitter, #filetree, #fileinfo, .vsplitbar').height(newH);
}
// Test if a given url exists
function file_exists (url) {
// http://kevin.vanzonneveld.net
// + original by: Enrique Gonzalez
// + input by: Jani Hartikainen
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// % note 1: This function uses XmlHttpRequest and cannot retrieve resource from different domain.
// % note 1: Synchronous so may lock up browser, mainly here for study purposes.
// * example 1: file_exists('http://kevin.vanzonneveld.net/pj_test_supportfile_1.htm');
// * returns 1: '123'
var req = this.window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
if (!req) {
throw new Error('XMLHttpRequest not supported');
}
// HEAD Results are usually shorter (faster) than GET
req.open('HEAD', url, false);
req.send(null);
if (req.status == 200) {
return true;
}
return false;
}
// Sets the folder status, upload, and new folder functions
// to the path specified. Called on initial page load and
// whenever a new directory is selected.
var setUploader = function(path){
$('#currentpath').val(path);
$('#uploader h1').text(lg.current_folder+': ' + path);
$('#newfolder').unbind().click(function(){
// var foldername = prompt('Enter the name of the new folder:', 'My Folder');
var foldername = lg.default_foldername;
var msg = lg.prompt_foldername+': ';
var getFolderName = function(v, m){
if(v != 1) return false;
var fname = m.children('#fname').val();
if(fname != ''){
foldername = fname;
$.getJSON(fileConnector + '?mode=addfolder&path=' + $('#currentpath').val() + '&name=' + foldername, function(result){
if(result['Code'] == 0){
addFolder(result['Parent'], result['Name']);
getFolderInfo(result['Parent']);
} else {
$.prompt(result['Error']);
}
});
} else {
$.prompt(lg.no_foldername);
}
}
var btns = {};
btns[lg.create_folder] = true;
btns[lg.cancel] = false;
$.prompt(msg, {
callback: getFolderName,
buttons: btns
});
});
}
// Binds specific actions to the toolbar in detail views.
// Called when detail views are loaded.
var bindToolbar = function(data){
// this little bit is purely cosmetic
$('#fileinfo').find('button').wrapInner('');
$('#fileinfo').find('button#select').click(function () { selectItem(data); }).show();
if(window.opener || window.tinyMCEPopup) {
$('#preview img').attr('title', lg.select);
$('#preview img').click(function () { selectItem(data); }).css("cursor", "pointer");
}
$('#fileinfo').find('button#rename').click(function(){
var newName = renameItem(data);
if(newName.length) $('#fileinfo > h1').text(newName);
}).show();
$('#fileinfo').find('button#delete').click(function(){
if(deleteItem(data)) $('#fileinfo').html('
' + lg.select_from_left + '
');
}).show();
$('#fileinfo').find('button#download').click(function(){
window.location = fileConnector + '?mode=download&path=' + encodeURIComponent(data['Path']);
}).show();
}
// Converts bytes to kb, mb, or gb as needed for display.
var formatBytes = function(bytes){
var n = parseFloat(bytes);
var d = parseFloat(1024);
var c = 0;
var u = [' bytes','kb','mb','gb'];
while(true){
if(n < d){
n = Math.round(n * 100) / 100;
return n + u[c];
} else {
n /= d;
c += 1;
}
}
}
/*---------------------------------------------------------
Item Actions
---------------------------------------------------------*/
// Calls the SetUrl function for FCKEditor compatibility,
// passes file path, dimensions, and alt text back to the
// opening window. Triggered by clicking the "Select"
// button in detail views or choosing the "Select"
// contextual menu option in list views.
// NOTE: closes the window when finished.
var selectItem = function(data){
if(window.opener){
if($.urlParam('CKEditor')){
// use CKEditor 3.0 integration method
window.opener.CKEDITOR.tools.callFunction($.urlParam('CKEditorFuncNum'), data['Path_real']);
} else {
// use FCKEditor 2.0 integration method
if(data['Properties']['Width'] != ''){
var p = data['Path_real'];
var w = data['Properties']['Width'];
var h = data['Properties']['Height'];
window.opener.SetUrl(p,w,h);
} else {
window.opener.SetUrl(data['Path_real']);
}
}
window.close();
//crmv@24011
} else if($.urlParam('HtmlReader')) {
fileContent = parent.getFile(data['Path_real']);
for(key in parent.CKEDITOR.instances){
var oEditor = parent.CKEDITOR.instances[key];
oEditor.insertHtml(fileContent);
}
parent.jQuery.fancybox.close();
//crmv@24011e
} else {
$.prompt(lg.fck_select_integration);
}
}
// Renames the current item and returns the new name.
// Called by clicking the "Rename" button in detail views
// or choosing the "Rename" contextual menu option in
// list views.
var renameItem = function(data){
var finalName = '';
var msg = lg.new_filename+': ';
var getNewName = function(v, m){
if(v != 1) return false;
rname = m.children('#rname').val();
if(rname != ''){
var givenName = rname;
var oldPath = data['Path'];
var connectString = fileConnector + '?mode=rename&old=' + data['Path'] + '&new=' + givenName;
$.ajax({
type: 'GET',
url: connectString,
dataType: 'json',
async: false,
success: function(result){
if(result['Code'] == 0){
var newPath = result['New Path'];
var newName = result['New Name'];
updateNode(oldPath, newPath, newName);
if($('#fileinfo').data('view') == 'grid'){
$('#fileinfo img[alt="' + oldPath + '"]').next('p').text(newName);
$('#fileinfo img[alt="' + oldPath + '"]').attr('alt', newPath);
} else {
$('#fileinfo td[title="' + oldPath + '"]').text(newName);
$('#fileinfo td[title="' + oldPath + '"]').attr('title', newPath);
}
$.prompt('Rename successful.');
} else {
$.prompt(result['Error']);
}
finalName = result['New Name'];
}
});
}
}
$.prompt(msg, {
callback: getNewName,
buttons: { 'Rename': 1, 'Cancel': 0 }
});
return finalName;
}
// Prompts for confirmation, then deletes the current item.
// Called by clicking the "Delete" button in detail views
// or choosing the "Delete contextual menu item in list views.
var deleteItem = function(data){
var isDeleted = false;
var msg = lg.confirmation_delete;
var doDelete = function(v, m){
if(v != 1) return false;
var connectString = fileConnector + '?mode=delete&path=' + data['Path'];
$.ajax({
type: 'GET',
url: connectString,
dataType: 'json',
async: false,
success: function(result){
if(result['Code'] == 0){
removeNode(result['Path']);
isDeleted = true;
$.prompt(lg.successful_delete);
} else {
isDeleted = false;
$.prompt(result['Error']);
}
}
});
}
$.prompt(msg, {
callback: doDelete,
buttons: { 'Yes': 1, 'No': 0 }
});
return isDeleted;
}
/*---------------------------------------------------------
Functions to Update the File Tree
---------------------------------------------------------*/
// Adds a new node as the first item beneath the specified
// parent node. Called after a successful file upload.
var addNode = function(path, name){
var ext = name.substr(name.lastIndexOf('.') + 1);
var thisNode = $('#filetree').find('a[rel="' + path + '"]');
var parentNode = thisNode.parent();
var newNode = '
');
parentNode.find('ul').prepend(newNode);
thisNode.click().click();
getFolderInfo(path);
$.prompt(lg.successful_added_file);
}
// Updates the specified node with a new name. Called after
// a successful rename operation.
var updateNode = function(oldPath, newPath, newName){
var thisNode = $('#filetree').find('a[rel="' + oldPath + '"]');
var parentNode = thisNode.parent().parent().prev('a');
thisNode.attr('rel', newPath).text(newName);
parentNode.click().click();
}
// Removes the specified node. Called after a successful
// delete operation.
var removeNode = function(path){
$('#filetree')
.find('a[rel="' + path + '"]')
.parent()
.fadeOut('slow', function(){
$(this).remove();
});
}
// Adds a new folder as the first item beneath the
// specified parent node. Called after a new folder is
// successfully created.
var addFolder = function(parent, name){
var newNode = '
';
var parentNode = $('#filetree').find('a[rel="' + parent + '"]');
if(parent != fileRoot){
parentNode.next('ul').prepend(newNode).prev('a').click().click();
} else {
$('#filetree > ul').append(newNode);
}
$.prompt(lg.successful_added_folder);
}
/*---------------------------------------------------------
Functions to Retrieve File and Folder Details
---------------------------------------------------------*/
// Decides whether to retrieve file or folder info based on
// the path provided.
var getDetailView = function(path){
if(path.lastIndexOf('/') == path.length - 1){
getFolderInfo(path);
$('#filetree').find('a[rel="' + path + '"]').click();
} else {
getFileInfo(path);
}
}
// Binds contextual menus to items in list and grid views.
var setMenus = function(action, path){
$.getJSON(fileConnector + '?mode=getinfo&path=' + path, function(data){
if($('#fileinfo').data('view') == 'grid'){
var item = $('#fileinfo').find('img[alt="' + data['Path'] + '"]').parent();
} else {
var item = $('#fileinfo').find('td[title="' + data['Path'] + '"]').parent();
}
switch(action){
case 'select':
selectItem(data);
break;
case 'download':
window.location = fileConnector + '?mode=download&path=' + data['Path'];
break;
case 'rename':
var newName = renameItem(data);
break;
case 'delete':
// TODO: When selected, the file is deleted and the
// file tree is updated, but the grid/list view is not.
if(deleteItem(data)) item.fadeOut('slow', function(){ $(this).remove(); });
break;
}
});
}
// Retrieves information about the specified file as a JSON
// object and uses that data to populate a template for
// detail views. Binds the toolbar for that detail view to
// enable specific actions. Called whenever an item is
// clicked in the file tree or list views.
var getFileInfo = function(file){
// Update location for status, upload, & new folder functions.
var currentpath = file.substr(0, file.lastIndexOf('/') + 1);
setUploader(currentpath);
// Include the template.
var template = '
';
template += '';
$('#fileinfo').html(template);
$('#parentfolder').click(function() {getFolderInfo(currentpath);});
// Retrieve the data & populate the template.
var d = new Date(); // to prevent IE cache issues
$.getJSON(fileConnector + '?mode=getinfo&path=' + encodeURIComponent(file) + '&time=' + d.getMilliseconds(), function(data){
if(data['Code'] == 0){
$('#fileinfo').find('h1').text(data['Filename']).attr('title', file);
$('#fileinfo').find('img').attr('src',data['Preview']);
var properties = '';
if(data['Properties']['Width'] && data['Properties']['Width'] != '') properties += '
';
$('#fileinfo').find('dl').html(properties);
// Bind toolbar functions.
bindToolbar(data);
} else {
$.prompt(data['Error']);
}
});
}
// Retrieves data for all items within the given folder and
// creates a list view. Binds contextual menu options.
// TODO: consider stylesheet switching to switch between grid
// and list views with sorting options.
var getFolderInfo = function(path){
// Update location for status, upload, & new folder functions.
setUploader(path);
// Display an activity indicator.
$('#fileinfo').html('');
// Retrieve the data and generate the markup.
$.getJSON(fileConnector + '?path=' + path + '&mode=getfolder&showThumbs=' + showThumbs, function(data){
var result = '';
if(data){
if($('#fileinfo').data('view') == 'grid'){
result += '
';
for(key in data){
var props = data[key]['Properties'];
var scaledWidth = 64;
var actualWidth = props['Width'];
if(actualWidth > 1 && actualWidth < scaledWidth) scaledWidth = actualWidth;
result += '