-removed windows CRLF

This commit is contained in:
denise 2012-09-18 17:26:34 -04:00
parent 610a5da24e
commit f9778f2da4
1 changed files with 378 additions and 378 deletions

View File

@ -1,378 +1,378 @@
/* /*
author: ApmeM (artem.votincev@gmail.com) author: ApmeM (artem.votincev@gmail.com)
date: 9-June-2010 date: 9-June-2010
version: 1.4 version: 1.4
download: http://code.google.com/p/jq-serverbrowse/ download: http://code.google.com/p/jq-serverbrowse/
*/ */
(function($) { (function($) {
$.fn.serverBrowser = function(settings) { $.fn.serverBrowser = function(settings) {
this.each(function() { this.each(function() {
var config = { var config = {
// Event function // Event function
// Appear when user click 'Ok' button, or doubleclick on file // Appear when user click 'Ok' button, or doubleclick on file
onSelect: function(file) { onSelect: function(file) {
alert('You select: ' + file); alert('You select: ' + file);
}, },
onLoad: function() { onLoad: function() {
return config.basePath; return config.basePath;
}, },
multiselect: false, multiselect: false,
// Image parameters // Image parameters
// System images (loading.gif, unknown.png, folder.png and images from knownPaths) will be referenced to systemImageUrl // System images (loading.gif, unknown.png, folder.png and images from knownPaths) will be referenced to systemImageUrl
// if systemImageUrl is empty or not specified - imageUrl will be taken // if systemImageUrl is empty or not specified - imageUrl will be taken
// All other images (like images for extension) will be taken from imageUrl // All other images (like images for extension) will be taken from imageUrl
imageUrl: 'img/', imageUrl: 'img/',
systemImageUrl: '', systemImageUrl: '',
showUpInList: false, showUpInList: false,
// Path properties // Path properties
// Base path, that links should start from. // Base path, that links should start from.
// If opened path is not under this path, alert will be shown and nothing will be opened // If opened path is not under this path, alert will be shown and nothing will be opened
// Path separator, that will be used to split specified paths and join paths to a string // Path separator, that will be used to split specified paths and join paths to a string
basePath: 'C:', basePath: 'C:',
separatorPath: '/', separatorPath: '/',
// Paths, that will be displayed on the left side of the dialog // Paths, that will be displayed on the left side of the dialog
// This is a link to specified paths on the server // This is a link to specified paths on the server
useKnownPaths: true, useKnownPaths: true,
knownPaths: [{text:'Desktop', image:'desktop.png', path:'C:/Users/All Users/Desktop'}, knownPaths: [{text:'Desktop', image:'desktop.png', path:'C:/Users/All Users/Desktop'},
{text:'Documents', image:'documents.png', path:'C:/Users/All Users/Documents'}], {text:'Documents', image:'documents.png', path:'C:/Users/All Users/Documents'}],
// Images for known extension (like 'png', 'exe', 'zip'), that will be displayed with its real names // Images for known extension (like 'png', 'exe', 'zip'), that will be displayed with its real names
// Images, that is not in this list will be referenced to 'unknown.png' image // Images, that is not in this list will be referenced to 'unknown.png' image
// If list is empty - all images is known. // If list is empty - all images is known.
knownExt: [], knownExt: [],
// Server path to this plugin handler // Server path to this plugin handler
handlerUrl: 'browserDlg.txt', handlerUrl: 'browserDlg.txt',
// JQuery-ui dialog settings // JQuery-ui dialog settings
title: 'Browse', title: 'Browse',
width: 300, width: 300,
height: 300, height: 300,
position: ['center', 'top'], position: ['center', 'top'],
// Administrative parameters used to // Administrative parameters used to
// help programmer or system administrator // help programmer or system administrator
requestMethod: 'POST', requestMethod: 'POST',
}; };
if (settings) $.extend(config, settings); if (settings) $.extend(config, settings);
// Required configuration elements // Required configuration elements
// We need to set some configuration elements without user // We need to set some configuration elements without user
// For example there should be 2 buttons on the bottom, // For example there should be 2 buttons on the bottom,
// And dialog should be opened after button is pressed, not when it created // And dialog should be opened after button is pressed, not when it created
// Also we need to know about dialog resizing // Also we need to know about dialog resizing
$.extend(config, { $.extend(config, {
autoOpen: false, autoOpen: false,
modal: true, modal: true,
buttons: [ buttons: [
{ {
text: "Cancel", text: "Cancel",
"class": "btn", "class": "btn",
click: function() { click: function() {
browserDlg.dialog("close"); browserDlg.dialog("close");
} }
}, },
{ {
text: "Open", text: "Open",
"class": "btn", "class": "btn",
click: function() { click: function() {
doneOk(); doneOk();
} }
} }
], ],
resize: function(event, ui) { resize: function(event, ui) {
recalculateSize(event, ui); recalculateSize(event, ui);
}, },
}); });
function systemImageUrl() function systemImageUrl()
{ {
if (config.systemImageUrl.length == 0) { if (config.systemImageUrl.length == 0) {
return config.imageUrl; return config.imageUrl;
} else{ } else{
return config.systemImageUrl; return config.systemImageUrl;
} }
} }
var privateConfig = { var privateConfig = {
// This stack array will store history navigation data // This stack array will store history navigation data
// When user open new directory, old directory will be added to this list // When user open new directory, old directory will be added to this list
// If user want, he will be able to move back by this history // If user want, he will be able to move back by this history
browserHistory: [], browserHistory: [],
// This array contains all currently selected items // This array contains all currently selected items
// When user select element, it will add associated path into this array // When user select element, it will add associated path into this array
// When user deselect element - associated path will be removed // When user deselect element - associated path will be removed
// Exception: if 'config.multiselect' is false, only one element will be stored in this array. // Exception: if 'config.multiselect' is false, only one element will be stored in this array.
selectedItems: [], selectedItems: [],
} }
// Main dialog div // Main dialog div
// It will be converted into jQuery-ui dialog box using my configuration parameters // It will be converted into jQuery-ui dialog box using my configuration parameters
// It contains 3 divs // It contains 3 divs
var browserDlg = $('<div title="' + config.title + '"></div>').css({'overflow': 'hidden'}).appendTo(document.body); var browserDlg = $('<div title="' + config.title + '"></div>').css({'overflow': 'hidden'}).appendTo(document.body);
browserDlg.dialog(config); browserDlg.dialog(config);
// First div on the top // First div on the top
// It contains textbox field and buttons // It contains textbox field and buttons
// User can enter any paths he want to open in this textbox and press enter // User can enter any paths he want to open in this textbox and press enter
// There is 3 buttons on the panel: // There is 3 buttons on the panel:
var enterPathDiv = $('<div></div>').addClass('ui-widget-content').appendTo(browserDlg).css({'height': '30px', 'width': '100%', 'padding-top': '7px'}); var enterPathDiv = $('<div></div>').addClass('ui-widget-content').appendTo(browserDlg).css({'height': '30px', 'width': '100%', 'padding-top': '7px'});
var enterButton = $('<div></div>').css({'float': 'left', 'vertical-align': 'middle', 'margin-left': '6px'}).addClass('ui-corner-all').hover( var enterButton = $('<div></div>').css({'float': 'left', 'vertical-align': 'middle', 'margin-left': '6px'}).addClass('ui-corner-all').hover(
function() { $(this).addClass('ui-state-hover'); }, function() { $(this).addClass('ui-state-hover'); },
function() { $(this).removeClass('ui-state-hover'); } function() { $(this).removeClass('ui-state-hover'); }
); );
var enterLabel = $('<span></span>').text('Look in: ').appendTo(enterButton.clone(false).appendTo(enterPathDiv)); var enterLabel = $('<span></span>').text('Look in: ').appendTo(enterButton.clone(false).appendTo(enterPathDiv));
var enterText = $('<input type="text">').keypress(function(e) { var enterText = $('<input type="text">').keypress(function(e) {
if (e.keyCode == '13') { if (e.keyCode == '13') {
e.preventDefault(); e.preventDefault();
loadPath(enterText.val()); loadPath(enterText.val());
} }
}).appendTo(enterButton.clone(false).appendTo(enterPathDiv)); }).appendTo(enterButton.clone(false).appendTo(enterPathDiv));
// Back button. // Back button.
// When user click on it, 2 last elements of the history pop from the list, and reload second of them. // When user click on it, 2 last elements of the history pop from the list, and reload second of them.
var enterBack = $('<div></div>').addClass('ui-corner-all ui-icon ui-icon-circle-arrow-w').click(function(){ var enterBack = $('<div></div>').addClass('ui-corner-all ui-icon ui-icon-circle-arrow-w').click(function(){
privateConfig.browserHistory.pop(); // Remove current element. It is not required now. privateConfig.browserHistory.pop(); // Remove current element. It is not required now.
var backPath = config.basePath; var backPath = config.basePath;
if(privateConfig.browserHistory.length > 0){ if(privateConfig.browserHistory.length > 0){
backPath = privateConfig.browserHistory.pop(); backPath = privateConfig.browserHistory.pop();
} }
loadPath(backPath); loadPath(backPath);
}).appendTo(enterButton.clone(true).appendTo(enterPathDiv)); }).appendTo(enterButton.clone(true).appendTo(enterPathDiv));
// Level Up Button // Level Up Button
// When user click on it, last element of the history will be taken, and '..' will be applied to the end of the array. // When user click on it, last element of the history will be taken, and '..' will be applied to the end of the array.
var enterUp = $('<div></div>').addClass('ui-corner-all ui-icon ui-icon-arrowreturnthick-1-n').click(function(){ var enterUp = $('<div></div>').addClass('ui-corner-all ui-icon ui-icon-arrowreturnthick-1-n').click(function(){
backPath = privateConfig.browserHistory[privateConfig.browserHistory.length - 1]; backPath = privateConfig.browserHistory[privateConfig.browserHistory.length - 1];
if(backPath != config.basePath){ if(backPath != config.basePath){
loadPath(backPath + config.separatorPath + '..'); loadPath(backPath + config.separatorPath + '..');
} }
}).appendTo(enterButton.clone(true).appendTo(enterPathDiv)); }).appendTo(enterButton.clone(true).appendTo(enterPathDiv));
// Second div is on the left // Second div is on the left
// It contains images and texts for pre-defined paths // It contains images and texts for pre-defined paths
// User just click on them and it will open pre-defined path // User just click on them and it will open pre-defined path
var knownPathDiv = $('<div></div>').addClass('ui-widget-content').css({'text-align':'center', 'overflow': 'auto', 'float': 'left', 'width': '100px'}); var knownPathDiv = $('<div></div>').addClass('ui-widget-content').css({'text-align':'center', 'overflow': 'auto', 'float': 'left', 'width': '100px'});
if(config.useKnownPaths){ if(config.useKnownPaths){
knownPathDiv.appendTo(browserDlg); knownPathDiv.appendTo(browserDlg);
$.each(config.knownPaths, function(index, path) { $.each(config.knownPaths, function(index, path) {
var knownDiv = $('<div></div>').css({'margin':'10px'}).hover( var knownDiv = $('<div></div>').css({'margin':'10px'}).hover(
function() { $(this).addClass('ui-state-hover'); }, function() { $(this).addClass('ui-state-hover'); },
function() { $(this).removeClass('ui-state-hover'); } function() { $(this).removeClass('ui-state-hover'); }
).click(function() { ).click(function() {
loadPath(path.path); loadPath(path.path);
}).appendTo(knownPathDiv); }).appendTo(knownPathDiv);
$('<img />').attr({ src: systemImageUrl() + config.separatorPath + path.image }).css({ width: '32px', margin: '5px 10px 5px 5px' }).appendTo(knownDiv); $('<img />').attr({ src: systemImageUrl() + config.separatorPath + path.image }).css({ width: '32px', margin: '5px 10px 5px 5px' }).appendTo(knownDiv);
$('<br/>').appendTo(knownDiv); $('<br/>').appendTo(knownDiv);
$('<span></span>').text(path.text).appendTo(knownDiv); $('<span></span>').text(path.text).appendTo(knownDiv);
}); });
} }
// Third div is everywhere :) // Third div is everywhere :)
// It show files and folders in the current path // It show files and folders in the current path
// User can click on path to select or deselect it // User can click on path to select or deselect it
// Doubleclick on path will open it // Doubleclick on path will open it
// Also doubleclick on file will select this file and close dialog // Also doubleclick on file will select this file and close dialog
var browserPathDiv = $('<div></div>').addClass('ui-widget-content').css({'float': 'right', 'overflow': 'auto'}).appendTo(browserDlg); var browserPathDiv = $('<div></div>').addClass('ui-widget-content').css({'float': 'right', 'overflow': 'auto'}).appendTo(browserDlg);
// Now everything is done // Now everything is done
// When user will be ready - he just click on the area you select for this plugin and dialog will appear // When user will be ready - he just click on the area you select for this plugin and dialog will appear
$(this).click(function() { $(this).click(function() {
privateConfig.browserHistory = []; privateConfig.browserHistory = [];
var startpath = removeBackPath(config.onLoad()); var startpath = removeBackPath(config.onLoad());
startpath = startpath.split(config.separatorPath); startpath = startpath.split(config.separatorPath);
startpath.pop(); startpath.pop();
startpath = startpath.join(config.separatorPath); startpath = startpath.join(config.separatorPath);
if(!checkBasePath(startpath)){ if(!checkBasePath(startpath)){
startpath = config.basePath; startpath = config.basePath;
} }
loadPath(startpath); loadPath(startpath);
browserDlg.dialog('open'); browserDlg.dialog('open');
recalculateSize(); recalculateSize();
}); });
// Function check if specified path is a child path of a 'config.basePath' // Function check if specified path is a child path of a 'config.basePath'
// If it is not - user should see message, that path invalid, or path should be changed to valid. // If it is not - user should see message, that path invalid, or path should be changed to valid.
function checkBasePath(path){ function checkBasePath(path){
if(config.basePath == '') if(config.basePath == '')
return true; return true;
var confPath = config.basePath.split(config.separatorPath); var confPath = config.basePath.split(config.separatorPath);
var curPath = path.split(config.separatorPath); var curPath = path.split(config.separatorPath);
if(confPath.length > curPath.length) if(confPath.length > curPath.length)
return false; return false;
var result = true; var result = true;
$.each(confPath, function(index, partConfPath) { $.each(confPath, function(index, partConfPath) {
if(partConfPath != curPath[index]){ if(partConfPath != curPath[index]){
result = false; result = false;
} }
}); });
return result; return result;
} }
// Function remove '..' parts of the path // Function remove '..' parts of the path
// Process depend on config.separatorPath option // Process depend on config.separatorPath option
// On the server side you need to check / or \ separators // On the server side you need to check / or \ separators
function removeBackPath(path){ function removeBackPath(path){
var confPath = config.basePath.split(config.separatorPath); var confPath = config.basePath.split(config.separatorPath);
var curPath = path.split(config.separatorPath); var curPath = path.split(config.separatorPath);
var newcurPath = []; var newcurPath = [];
$.each(curPath, function(index, partCurPath) { $.each(curPath, function(index, partCurPath) {
if(partCurPath == ".."){ if(partCurPath == ".."){
newcurPath.pop(); newcurPath.pop();
}else{ }else{
newcurPath.push(partCurPath); newcurPath.push(partCurPath);
} }
}); });
return newcurPath.join(config.separatorPath); return newcurPath.join(config.separatorPath);
} }
// This function will be called when user click 'Open' // This function will be called when user click 'Open'
// It check if any path is selected, and call config.onSelect function with path list // It check if any path is selected, and call config.onSelect function with path list
function doneOk(){ function doneOk(){
var newCurPath = []; var newCurPath = [];
$.each(privateConfig.selectedItems, function(index, item) { $.each(privateConfig.selectedItems, function(index, item) {
newCurPath.push($.data(item, 'path')); newCurPath.push($.data(item, 'path'));
}); });
if(newCurPath.length == 0) { if(newCurPath.length == 0) {
newCurPath.push(privateConfig.browserHistory.pop()); newCurPath.push(privateConfig.browserHistory.pop());
} }
if(config.multiselect) if(config.multiselect)
config.onSelect(newCurPath); config.onSelect(newCurPath);
else { else {
if(newCurPath.length == 1) { if(newCurPath.length == 1) {
config.onSelect(newCurPath[0]); config.onSelect(newCurPath[0]);
} else if(newCurPath.length > 1){ } else if(newCurPath.length > 1){
alert('Plugin work incorrectly. If error repeat, please add issue into http://code.google.com/p/jq-serverbrowse/issues/list with steps to reproduce.'); alert('Plugin work incorrectly. If error repeat, please add issue into http://code.google.com/p/jq-serverbrowse/issues/list with steps to reproduce.');
return; return;
} }
} }
browserDlg.dialog("close"); browserDlg.dialog("close");
} }
// Function recalculate and set new width and height for left and right div elements // Function recalculate and set new width and height for left and right div elements
// height have '-2' because of the borders // height have '-2' because of the borders
// width have '-4' because of a border an 2 pixels space between divs // width have '-4' because of a border an 2 pixels space between divs
function recalculateSize(event, ui){ function recalculateSize(event, ui){
knownPathDiv.css({'height' : browserDlg.height() - enterPathDiv.outerHeight(true) - 2}); knownPathDiv.css({'height' : browserDlg.height() - enterPathDiv.outerHeight(true) - 2});
browserPathDiv.css({'height' : browserDlg.height() - enterPathDiv.outerHeight(true) - 2, browserPathDiv.css({'height' : browserDlg.height() - enterPathDiv.outerHeight(true) - 2,
'width' : browserDlg.width() - knownPathDiv.outerWidth(true) - 4}); 'width' : browserDlg.width() - knownPathDiv.outerWidth(true) - 4});
} }
// Function adds new element into browserPathDiv element depends on file parameters // Function adds new element into browserPathDiv element depends on file parameters
// If file.isError is set, error message will be displayed instead of clickable area // If file.isError is set, error message will be displayed instead of clickable area
// Clickable div contain image from extension and text from file parameter // Clickable div contain image from extension and text from file parameter
function addElement(file){ function addElement(file){
var itemDiv = $('<div></div>').css({ margin: '2px' }).appendTo(browserPathDiv); var itemDiv = $('<div></div>').css({ margin: '2px' }).appendTo(browserPathDiv);
if(file.isError) if(file.isError)
{ {
itemDiv.addClass('ui-state-error ui-corner-all').css({padding: '0pt 0.7em'}); itemDiv.addClass('ui-state-error ui-corner-all').css({padding: '0pt 0.7em'});
var p = $('<p></p>').appendTo(itemDiv); var p = $('<p></p>').appendTo(itemDiv);
$('<span></span>').addClass('ui-icon ui-icon-alert').css({'float': 'left', 'margin-right': '0.3em'}).appendTo(p); $('<span></span>').addClass('ui-icon ui-icon-alert').css({'float': 'left', 'margin-right': '0.3em'}).appendTo(p);
$('<span></span>').text(file.name).appendTo(p); $('<span></span>').text(file.name).appendTo(p);
}else }else
{ {
var fullPath = file.path + config.separatorPath + file.name; var fullPath = file.path + config.separatorPath + file.name;
itemDiv.hover( itemDiv.hover(
function() { $(this).addClass('ui-state-hover'); }, function() { $(this).addClass('ui-state-hover'); },
function() { $(this).removeClass('ui-state-hover'); } function() { $(this).removeClass('ui-state-hover'); }
); );
var itemImage = $('<img />').css({ width: '16px', margin: '0 5px 0 0' }).appendTo(itemDiv); var itemImage = $('<img />').css({ width: '16px', margin: '0 5px 0 0' }).appendTo(itemDiv);
var itemText = $('<span></span>').text(file.name).appendTo(itemDiv); var itemText = $('<span></span>').text(file.name).appendTo(itemDiv);
if (file.isFolder) if (file.isFolder)
itemImage.attr({ src: systemImageUrl() + 'folder.png' }); itemImage.attr({ src: systemImageUrl() + 'folder.png' });
else { else {
ext = file.name.split('.').pop(); ext = file.name.split('.').pop();
var res = ''; var res = '';
if (ext == '' || ext == file.name || (config.knownExt.length > 0 && $.inArray(ext, config.knownExt) < 0)) if (ext == '' || ext == file.name || (config.knownExt.length > 0 && $.inArray(ext, config.knownExt) < 0))
itemImage.attr({ src: systemImageUrl() + 'unknown.png' }); itemImage.attr({ src: systemImageUrl() + 'unknown.png' });
else else
itemImage.attr({ src: config.imageUrl + ext + '.png' }); itemImage.attr({ src: config.imageUrl + ext + '.png' });
} }
$.data(itemDiv, 'path', fullPath); $.data(itemDiv, 'path', fullPath);
itemDiv.unbind('click').bind('click', function(e) { itemDiv.unbind('click').bind('click', function(e) {
if(!$(this).hasClass('ui-state-active')) { if(!$(this).hasClass('ui-state-active')) {
if(!config.multiselect && privateConfig.selectedItems.length > 0) { if(!config.multiselect && privateConfig.selectedItems.length > 0) {
$(privateConfig.selectedItems[0]).click(); $(privateConfig.selectedItems[0]).click();
} }
privateConfig.selectedItems.push(itemDiv); privateConfig.selectedItems.push(itemDiv);
}else{ }else{
var newCurPath = []; var newCurPath = [];
$.each(privateConfig.selectedItems, function(index, item) { $.each(privateConfig.selectedItems, function(index, item) {
if($.data(item, 'path') != fullPath) if($.data(item, 'path') != fullPath)
newCurPath.push(item); newCurPath.push(item);
}); });
privateConfig.selectedItems = newCurPath; privateConfig.selectedItems = newCurPath;
} }
$(this).toggleClass('ui-state-active'); $(this).toggleClass('ui-state-active');
}); });
itemDiv.unbind('dblclick').bind('dblclick', function(e) { itemDiv.unbind('dblclick').bind('dblclick', function(e) {
if (file.isFolder){ if (file.isFolder){
loadPath(fullPath); loadPath(fullPath);
} else { } else {
privateConfig.selectedItems = [itemDiv]; privateConfig.selectedItems = [itemDiv];
doneOk(); doneOk();
} }
}); });
} }
} }
// Main plugin function // Main plugin function
// When user enter path manually, select it from pre-defined path, or doubleclick in browser this function will call // When user enter path manually, select it from pre-defined path, or doubleclick in browser this function will call
// It send a request on the server to retrieve child directories and files of the specified path // It send a request on the server to retrieve child directories and files of the specified path
// If path is not under 'config.basePath', alert will be shown and nothing will be opened // If path is not under 'config.basePath', alert will be shown and nothing will be opened
function loadPath(path) { function loadPath(path) {
privateConfig.selectedItems = []; privateConfig.selectedItems = [];
// First we need to remove all '..' parts of the path // First we need to remove all '..' parts of the path
path = removeBackPath(path); path = removeBackPath(path);
// Then we need to check, if path based on 'config.basePath' // Then we need to check, if path based on 'config.basePath'
if(!checkBasePath(path)) { if(!checkBasePath(path)) {
alert('Path should be based from ' + config.basePath); alert('Path should be based from ' + config.basePath);
return; return;
} }
// Then we can put this path into history // Then we can put this path into history
privateConfig.browserHistory.push(path); privateConfig.browserHistory.push(path);
// Show it to user // Show it to user
enterText.val(path); enterText.val(path);
// And load // And load
$.ajax({ $.ajax({
url: config.handlerUrl, url: config.handlerUrl,
type: config.requestMethod, type: config.requestMethod,
data: { data: {
action: 'browse', action: 'browse',
path: path, path: path,
time: new Date().getTime() time: new Date().getTime()
}, },
beforeSend: function() { beforeSend: function() {
browserPathDiv.empty().css({ 'text-align': 'center' }); browserPathDiv.empty().css({ 'text-align': 'center' });
$('<img />').attr({ src: systemImageUrl() + 'loading.gif' }).css({ width: '32px' }).appendTo(browserPathDiv); $('<img />').attr({ src: systemImageUrl() + 'loading.gif' }).css({ width: '32px' }).appendTo(browserPathDiv);
}, },
success: function(files) { success: function(files) {
browserPathDiv.empty().css({ 'text-align': 'left' }); browserPathDiv.empty().css({ 'text-align': 'left' });
if(path != config.basePath && config.showUpInList){ if(path != config.basePath && config.showUpInList){
addElement({name: '..', isFolder: true, isError: false, path: path}); addElement({name: '..', isFolder: true, isError: false, path: path});
} }
$.each(files, function(index, file) { $.each(files, function(index, file) {
addElement($.extend(file, {path: path})); addElement($.extend(file, {path: path}));
}); });
}, },
dataType: 'json' dataType: 'json'
}); });
} }
}); });
return this; return this;
}; };
})(jQuery); })(jQuery);