You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

filelist.js 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. var FileList={
  2. useUndo:true,
  3. update:function(fileListHtml) {
  4. $('#fileList').empty().html(fileListHtml);
  5. },
  6. addFile:function(name,size,lastModified,loading,hidden){
  7. var basename, extension, simpleSize, sizeColor, lastModifiedTime, modifiedColor,
  8. img=(loading)?OC.imagePath('core', 'loading.gif'):OC.imagePath('core', 'filetypes/file.png'),
  9. html='<tr data-type="file" data-size="'+size+'" data-permissions="'+$('#permissions').val()+'">';
  10. if(name.indexOf('.')!=-1){
  11. basename=name.substr(0,name.lastIndexOf('.'));
  12. extension=name.substr(name.lastIndexOf('.'));
  13. }else{
  14. basename=name;
  15. extension=false;
  16. }
  17. html+='<td class="filename" style="background-image:url('+img+')"><input type="checkbox" />';
  18. html+='<a class="name" href="download.php?file='+$('#dir').val().replace(/</, '&lt;').replace(/>/, '&gt;')+'/'+escapeHTML(name)+'"><span class="nametext">'+escapeHTML(basename);
  19. if(extension){
  20. html+='<span class="extension">'+escapeHTML(extension)+'</span>';
  21. }
  22. html+='</span></a></td>';
  23. if(size!='Pending'){
  24. simpleSize=simpleFileSize(size);
  25. }else{
  26. simpleSize='Pending';
  27. }
  28. sizeColor = Math.round(200-size/(1024*1024)*2);
  29. lastModifiedTime=Math.round(lastModified.getTime() / 1000);
  30. modifiedColor=Math.round((Math.round((new Date()).getTime() / 1000)-lastModifiedTime)/60/60/24*14);
  31. html+='<td class="filesize" title="'+humanFileSize(size)+'" style="color:rgb('+sizeColor+','+sizeColor+','+sizeColor+')">'+simpleSize+'</td>';
  32. html+='<td class="date"><span class="modified" title="'+formatDate(lastModified)+'" style="color:rgb('+modifiedColor+','+modifiedColor+','+modifiedColor+')">'+relative_modified_date(lastModified.getTime() / 1000)+'</span></td>';
  33. html+='</tr>';
  34. FileList.insertElement(name,'file',$(html).attr('data-file',name));
  35. var row = $('tr').filterAttr('data-file',name);
  36. if(loading){
  37. row.data('loading',true);
  38. }else{
  39. row.find('td.filename').draggable(dragOptions);
  40. }
  41. if (hidden) {
  42. row.hide();
  43. }
  44. FileActions.display(row.find('td.filename'));
  45. },
  46. addDir:function(name,size,lastModified,hidden){
  47. var html, td, link_elem, sizeColor, lastModifiedTime, modifiedColor;
  48. html = $('<tr></tr>').attr({ "data-type": "dir", "data-size": size, "data-file": name, "data-permissions": $('#permissions').val()});
  49. td = $('<td></td>').attr({"class": "filename", "style": 'background-image:url('+OC.imagePath('core', 'filetypes/folder.png')+')' });
  50. td.append('<input type="checkbox" />');
  51. link_elem = $('<a></a>').attr({ "class": "name", "href": OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent($('#dir').val()+'/'+name).replace(/%2F/g, '/') });
  52. link_elem.append($('<span></span>').addClass('nametext').text(name));
  53. link_elem.append($('<span></span>').attr({'class': 'uploadtext', 'currentUploads': 0}));
  54. td.append(link_elem);
  55. html.append(td);
  56. if(size!='Pending'){
  57. simpleSize=simpleFileSize(size);
  58. }else{
  59. simpleSize='Pending';
  60. }
  61. sizeColor = Math.round(200-Math.pow((size/(1024*1024)),2));
  62. lastModifiedTime=Math.round(lastModified.getTime() / 1000);
  63. modifiedColor=Math.round((Math.round((new Date()).getTime() / 1000)-lastModifiedTime)/60/60/24*5);
  64. td = $('<td></td>').attr({ "class": "filesize", "title": humanFileSize(size), "style": 'color:rgb('+sizeColor+','+sizeColor+','+sizeColor+')'}).text(simpleSize);
  65. html.append(td);
  66. td = $('<td></td>').attr({ "class": "date" });
  67. td.append($('<span></span>').attr({ "class": "modified", "title": formatDate(lastModified), "style": 'color:rgb('+modifiedColor+','+modifiedColor+','+modifiedColor+')' }).text( relative_modified_date(lastModified.getTime() / 1000) ));
  68. html.append(td);
  69. FileList.insertElement(name,'dir',html);
  70. var row = $('tr').filterAttr('data-file',name);
  71. row.find('td.filename').draggable(dragOptions);
  72. row.find('td.filename').droppable(folderDropOptions);
  73. if (hidden) {
  74. row.hide();
  75. }
  76. FileActions.display(row.find('td.filename'));
  77. },
  78. refresh:function(data) {
  79. var result = jQuery.parseJSON(data.responseText);
  80. if(typeof(result.data.breadcrumb) != 'undefined'){
  81. updateBreadcrumb(result.data.breadcrumb);
  82. }
  83. FileList.update(result.data.files);
  84. resetFileActionPanel();
  85. },
  86. remove:function(name){
  87. $('tr').filterAttr('data-file',name).find('td.filename').draggable('destroy');
  88. $('tr').filterAttr('data-file',name).remove();
  89. if($('tr[data-file]').length==0){
  90. $('#emptyfolder').show();
  91. }
  92. },
  93. insertElement:function(name,type,element){
  94. //find the correct spot to insert the file or folder
  95. var pos, fileElements=$('tr[data-file][data-type="'+type+'"]:visible');
  96. if(name.localeCompare($(fileElements[0]).attr('data-file'))<0){
  97. pos=-1;
  98. }else if(name.localeCompare($(fileElements[fileElements.length-1]).attr('data-file'))>0){
  99. pos=fileElements.length-1;
  100. }else{
  101. for(pos=0;pos<fileElements.length-1;pos++){
  102. if(name.localeCompare($(fileElements[pos]).attr('data-file'))>0 && name.localeCompare($(fileElements[pos+1]).attr('data-file'))<0){
  103. break;
  104. }
  105. }
  106. }
  107. if(fileElements.length){
  108. if(pos==-1){
  109. $(fileElements[0]).before(element);
  110. }else{
  111. $(fileElements[pos]).after(element);
  112. }
  113. }else if(type=='dir' && $('tr[data-file]').length>0){
  114. $('tr[data-file]').first().before(element);
  115. }else{
  116. $('#fileList').append(element);
  117. }
  118. $('#emptyfolder').hide();
  119. },
  120. loadingDone:function(name, id){
  121. var mime, tr=$('tr').filterAttr('data-file',name);
  122. tr.data('loading',false);
  123. mime=tr.data('mime');
  124. tr.attr('data-mime',mime);
  125. if (id != null) {
  126. tr.attr('data-id', id);
  127. }
  128. getMimeIcon(mime,function(path){
  129. tr.find('td.filename').attr('style','background-image:url('+path+')');
  130. });
  131. tr.find('td.filename').draggable(dragOptions);
  132. },
  133. isLoading:function(name){
  134. return $('tr').filterAttr('data-file',name).data('loading');
  135. },
  136. rename:function(name){
  137. var tr, td, input, form;
  138. tr=$('tr').filterAttr('data-file',name);
  139. tr.data('renaming',true);
  140. td=tr.children('td.filename');
  141. input=$('<input class="filename"/>').val(name);
  142. form=$('<form></form>');
  143. form.append(input);
  144. td.children('a.name').hide();
  145. td.append(form);
  146. input.focus();
  147. form.submit(function(event){
  148. event.stopPropagation();
  149. event.preventDefault();
  150. var newname=input.val();
  151. if (!Files.isFileNameValid(newname)) {
  152. return false;
  153. } else if (newname != name) {
  154. if (FileList.checkName(name, newname, false)) {
  155. newname = name;
  156. } else {
  157. $.get(OC.filePath('files','ajax','rename.php'), { dir : $('#dir').val(), newname: newname, file: name },function(result) {
  158. if (!result || result.status == 'error') {
  159. OC.dialogs.alert(result.data.message, 'Error moving file');
  160. newname = name;
  161. }
  162. });
  163. }
  164. }
  165. tr.data('renaming',false);
  166. tr.attr('data-file', newname);
  167. var path = td.children('a.name').attr('href');
  168. td.children('a.name').attr('href', path.replace(encodeURIComponent(name), encodeURIComponent(newname)));
  169. if (newname.indexOf('.') > 0 && tr.data('type') != 'dir') {
  170. var basename=newname.substr(0,newname.lastIndexOf('.'));
  171. } else {
  172. var basename=newname;
  173. }
  174. td.find('a.name span.nametext').text(basename);
  175. if (newname.indexOf('.') > 0 && tr.data('type') != 'dir') {
  176. if (td.find('a.name span.extension').length == 0 ) {
  177. td.find('a.name span.nametext').append('<span class="extension"></span>');
  178. }
  179. td.find('a.name span.extension').text(newname.substr(newname.lastIndexOf('.')));
  180. }
  181. form.remove();
  182. td.children('a.name').show();
  183. return false;
  184. });
  185. input.keyup(function(event){
  186. if (event.keyCode == 27) {
  187. tr.data('renaming',false);
  188. form.remove();
  189. td.children('a.name').show();
  190. }
  191. });
  192. input.click(function(event){
  193. event.stopPropagation();
  194. event.preventDefault();
  195. });
  196. input.blur(function(){
  197. form.trigger('submit');
  198. });
  199. },
  200. checkName:function(oldName, newName, isNewFile) {
  201. if (isNewFile || $('tr').filterAttr('data-file', newName).length > 0) {
  202. $('#notification').data('oldName', oldName);
  203. $('#notification').data('newName', newName);
  204. $('#notification').data('isNewFile', isNewFile);
  205. if (isNewFile) {
  206. OC.Notification.showHtml(t('files', '{new_name} already exists', {new_name: escapeHTML(newName)})+'<span class="replace">'+t('files', 'replace')+'</span><span class="suggest">'+t('files', 'suggest name')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>');
  207. } else {
  208. OC.Notification.showHtml(t('files', '{new_name} already exists', {new_name: escapeHTML(newName)})+'<span class="replace">'+t('files', 'replace')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>');
  209. }
  210. return true;
  211. } else {
  212. return false;
  213. }
  214. },
  215. replace:function(oldName, newName, isNewFile) {
  216. // Finish any existing actions
  217. if (FileList.lastAction || !FileList.useUndo) {
  218. FileList.lastAction();
  219. }
  220. $('tr').filterAttr('data-file', oldName).hide();
  221. $('tr').filterAttr('data-file', newName).hide();
  222. var tr = $('tr').filterAttr('data-file', oldName).clone();
  223. tr.attr('data-replace', 'true');
  224. tr.attr('data-file', newName);
  225. var td = tr.children('td.filename');
  226. td.children('a.name .span').text(newName);
  227. var path = td.children('a.name').attr('href');
  228. td.children('a.name').attr('href', path.replace(encodeURIComponent(oldName), encodeURIComponent(newName)));
  229. if (newName.indexOf('.') > 0) {
  230. var basename = newName.substr(0, newName.lastIndexOf('.'));
  231. } else {
  232. var basename = newName;
  233. }
  234. td.children('a.name').empty();
  235. var span = $('<span class="nametext"></span>');
  236. span.text(basename);
  237. td.children('a.name').append(span);
  238. if (newName.indexOf('.') > 0) {
  239. span.append($('<span class="extension">'+newName.substr(newName.lastIndexOf('.'))+'</span>'));
  240. }
  241. FileList.insertElement(newName, tr.data('type'), tr);
  242. tr.show();
  243. FileList.replaceCanceled = false;
  244. FileList.replaceOldName = oldName;
  245. FileList.replaceNewName = newName;
  246. FileList.replaceIsNewFile = isNewFile;
  247. FileList.lastAction = function() {
  248. FileList.finishReplace();
  249. };
  250. if (isNewFile) {
  251. OC.Notification.showHtml(t('files', 'replaced {new_name}', {new_name: newName})+'<span class="undo">'+t('files', 'undo')+'</span>');
  252. } else {
  253. OC.Notification.showHtml(t('files', 'replaced {new_name} with {old_name}', {new_name: newName}, {old_name: oldName})+'<span class="undo">'+t('files', 'undo')+'</span>');
  254. }
  255. },
  256. finishReplace:function() {
  257. if (!FileList.replaceCanceled && FileList.replaceOldName && FileList.replaceNewName) {
  258. $.ajax({url: OC.filePath('files', 'ajax', 'rename.php'), async: false, data: { dir: $('#dir').val(), newname: FileList.replaceNewName, file: FileList.replaceOldName }, success: function(result) {
  259. if (result && result.status == 'success') {
  260. $('tr').filterAttr('data-replace', 'true').removeAttr('data-replace');
  261. } else {
  262. OC.dialogs.alert(result.data.message, 'Error moving file');
  263. }
  264. FileList.replaceCanceled = true;
  265. FileList.replaceOldName = null;
  266. FileList.replaceNewName = null;
  267. FileList.lastAction = null;
  268. }});
  269. }
  270. },
  271. do_delete:function(files){
  272. // Finish any existing actions
  273. if (FileList.lastAction) {
  274. FileList.lastAction();
  275. }
  276. FileList.prepareDeletion(files);
  277. if (!FileList.useUndo) {
  278. FileList.lastAction();
  279. } else {
  280. // NOTE: Temporary fix to change the text to unshared for files in root of Shared folder
  281. if ($('#dir').val() == '/Shared') {
  282. OC.Notification.showHtml(t('files', 'unshared {files}', {'files': escapeHTML(files)})+'<span class="undo">'+t('files', 'undo')+'</span>');
  283. } else {
  284. OC.Notification.showHtml(t('files', 'deleted {files}', {'files': escapeHTML(files)})+'<span class="undo">'+t('files', 'undo')+'</span>');
  285. }
  286. }
  287. },
  288. finishDelete:function(ready,sync){
  289. if(!FileList.deleteCanceled && FileList.deleteFiles){
  290. var fileNames=JSON.stringify(FileList.deleteFiles);
  291. $.ajax({
  292. url: OC.filePath('files', 'ajax', 'delete.php'),
  293. async:!sync,
  294. type:'post',
  295. data: {dir:$('#dir').val(),files:fileNames},
  296. complete: function(data){
  297. boolOperationFinished(data, function(){
  298. OC.Notification.hide();
  299. $.each(FileList.deleteFiles,function(index,file){
  300. FileList.remove(file);
  301. });
  302. FileList.deleteCanceled=true;
  303. FileList.deleteFiles=null;
  304. FileList.lastAction = null;
  305. if(ready){
  306. ready();
  307. }
  308. });
  309. }
  310. });
  311. }
  312. },
  313. prepareDeletion:function(files){
  314. if(files.substr){
  315. files=[files];
  316. }
  317. $.each(files,function(index,file){
  318. var files = $('tr').filterAttr('data-file',file);
  319. files.hide();
  320. files.find('input[type="checkbox"]').removeAttr('checked');
  321. files.removeClass('selected');
  322. });
  323. procesSelection();
  324. FileList.deleteCanceled=false;
  325. FileList.deleteFiles=files;
  326. FileList.lastAction = function() {
  327. FileList.finishDelete(null, true);
  328. };
  329. }
  330. };
  331. $(document).ready(function(){
  332. $('#notification').hide();
  333. $('#notification .undo').live('click', function(){
  334. if (FileList.deleteFiles) {
  335. $.each(FileList.deleteFiles,function(index,file){
  336. $('tr').filterAttr('data-file',file).show();
  337. });
  338. FileList.deleteCanceled=true;
  339. FileList.deleteFiles=null;
  340. } else if (FileList.replaceOldName && FileList.replaceNewName) {
  341. if (FileList.replaceIsNewFile) {
  342. // Delete the new uploaded file
  343. FileList.deleteCanceled = false;
  344. FileList.deleteFiles = [FileList.replaceOldName];
  345. FileList.finishDelete(null, true);
  346. } else {
  347. $('tr').filterAttr('data-file', FileList.replaceOldName).show();
  348. }
  349. $('tr').filterAttr('data-replace', 'true').remove();
  350. $('tr').filterAttr('data-file', FileList.replaceNewName).show();
  351. FileList.replaceCanceled = true;
  352. FileList.replaceOldName = null;
  353. FileList.replaceNewName = null;
  354. FileList.replaceIsNewFile = null;
  355. }
  356. FileList.lastAction = null;
  357. OC.Notification.hide();
  358. });
  359. $('#notification .replace').live('click', function() {
  360. OC.Notification.hide(function() {
  361. FileList.replace($('#notification').data('oldName'), $('#notification').data('newName'), $('#notification').data('isNewFile'));
  362. });
  363. });
  364. $('#notification .suggest').live('click', function() {
  365. $('tr').filterAttr('data-file', $('#notification').data('oldName')).show();
  366. OC.Notification.hide();
  367. });
  368. $('#notification .cancel').live('click', function() {
  369. if ($('#notification').data('isNewFile')) {
  370. FileList.deleteCanceled = false;
  371. FileList.deleteFiles = [$('#notification').data('oldName')];
  372. FileList.finishDelete(null, true);
  373. }
  374. });
  375. FileList.useUndo=(window.onbeforeunload)?true:false;
  376. $(window).bind('beforeunload', function (){
  377. if (FileList.lastAction) {
  378. FileList.lastAction();
  379. }
  380. });
  381. $(window).unload(function (){
  382. $(window).trigger('beforeunload');
  383. });
  384. });