diff options
Diffstat (limited to 'apps/files/js/filelist.js')
-rw-r--r-- | apps/files/js/filelist.js | 740 |
1 files changed, 407 insertions, 333 deletions
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index cda4e823a73..509929d0e55 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -8,17 +8,104 @@ * */ -/* global OC, t, n, FileList, FileActions, Files */ -/* global procesSelection, dragOptions, SVGSupport, replaceSVG */ -window.FileList={ +/* global OC, t, n, FileList, FileActions, Files, BreadCrumb */ +/* global procesSelection, dragOptions, SVGSupport */ +window.FileList = { appName: t('files', 'Files'), + isEmpty: true, useUndo:true, - postProcessList: function() { - $('#fileList tr').each(function() { - //little hack to set unescape filenames in attribute - $(this).attr('data-file',decodeURIComponent($(this).attr('data-file'))); + $el: $('#filestable'), + $fileList: $('#fileList'), + breadcrumb: null, + initialized: false, + + /** + * Initialize the file list and its components + */ + initialize: function() { + var self = this; + if (this.initialized) { + return; + } + + // TODO: FileList should not know about global elements + this.$el = $('#filestable'); + this.$fileList = $('#fileList'); + + this.breadcrumb = new BreadCrumb({ + onClick: this._onClickBreadCrumb, + onDrop: this._onDropOnBreadCrumb, + getCrumbUrl: function(part, index) { + return self.linkTo(part.dir); + } + }); + + $('#controls').prepend(this.breadcrumb.$el); + + $(window).resize(function() { + // TODO: debounce this ? + var width = $(this).width(); + FileList.breadcrumb.resize(width, false); + }); + }, + + /** + * Event handler when clicking on a bread crumb + */ + _onClickBreadCrumb: function(e) { + var $el = $(e.target).closest('.crumb'), + $targetDir = $el.data('dir'); + + if ($targetDir !== undefined) { + e.preventDefault(); + FileList.changeDirectory($targetDir); + } + }, + + /** + * Event handler when dropping on a breadcrumb + */ + _onDropOnBreadCrumb: function( event, ui ) { + var target=$(this).data('dir'); + var dir = FileList.getCurrentDirectory(); + while(dir.substr(0,1) === '/') {//remove extra leading /'s + dir=dir.substr(1); + } + dir = '/' + dir; + if (dir.substr(-1,1) !== '/') { + dir = dir + '/'; + } + if (target === dir || target+'/' === dir) { + return; + } + var files = ui.helper.find('tr'); + $(files).each(function(i,row) { + var dir = $(row).data('dir'); + var file = $(row).data('filename'); + //slapdash selector, tracking down our original element that the clone budded off of. + var origin = $('tr[data-id=' + $(row).data('origin') + ']'); + var td = origin.children('td.filename'); + var oldBackgroundImage = td.css('background-image'); + td.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')'); + $.post(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: target }, function(result) { + if (result) { + if (result.status === 'success') { + FileList.remove(file); + procesSelection(); + $('#notification').hide(); + } else { + $('#notification').hide(); + $('#notification').text(result.data.message); + $('#notification').fadeIn(); + } + } else { + OC.dialogs.alert(t('files', 'Error moving file'), t('files', 'Error')); + } + td.css('background-image', oldBackgroundImage); + }); }); }, + /** * Sets a new page title */ @@ -36,64 +123,133 @@ window.FileList={ }, /** * Returns the tr element for a given file name + * @param fileName file name */ findFileEl: function(fileName){ // use filterAttr to avoid escaping issues - return $('#fileList tr').filterAttr('data-file', fileName); + return this.$fileList.find('tr').filterAttr('data-file', fileName); }, - update:function(fileListHtml) { - var $fileList = $('#fileList'); - $fileList.empty().html(fileListHtml); - FileList.updateEmptyContent(); - $fileList.find('tr').each(function () { - FileActions.display($(this).children('td.filename')); - }); - $fileList.trigger(jQuery.Event("fileActionsReady")); - FileList.postProcessList(); + /** + * Sets the files to be displayed in the list. + * This operation will rerender the list and update the summary. + * @param filesArray array of file data (map) + */ + setFiles:function(filesArray) { + // detach to make adding multiple rows faster + this.$fileList.detach(); + + this.$fileList.empty(); + + this.isEmpty = filesArray.length === 0; + for (var i = 0; i < filesArray.length; i++) { + this.add(filesArray[i], {updateSummary: false}); + } + + this.$el.find('thead').after(this.$fileList); + + this.updateEmptyContent(); + this.$fileList.trigger(jQuery.Event("fileActionsReady")); // "Files" might not be loaded in extending apps if (window.Files) { Files.setupDragAndDrop(); } - FileList.updateFileSummary(); + this.updateFileSummary(); procesSelection(); - $(window).scrollTop(0); - $fileList.trigger(jQuery.Event("updated")); + + this.$fileList.trigger(jQuery.Event("updated")); + }, + /** + * If SVG is not supported, replaces the given images's extension + * from ".svg" to ".png". + * If SVG is supported, return the image path as is. + * @param icon image path + * @return fixed image path + */ + _replaceSVG: function(icon) { + if (!SVGSupport()) { + var i = icon.lastIndexOf('.svg'); + if (i >= 0) { + icon = icon.substr(0, i) + '.png' + icon.substr(i+4); + } + } + return icon; }, - createRow:function(type, name, iconurl, linktarget, size, lastModified, permissions) { - var td, simpleSize, basename, extension; + /** + * Creates a new table row element using the given file data. + * @param fileData map of file attributes + * @param options map of attribute "loading" whether the entry is currently loading + * @return new tr element (not appended to the table) + */ + _createRow: function(fileData, options) { + var td, simpleSize, basename, extension, sizeColor, + icon = FileList._replaceSVG(fileData.icon), + name = fileData.name, + type = fileData.type || 'file', + mtime = parseInt(fileData.mtime, 10) || new Date().getTime(), + mime = fileData.mimetype, + linkUrl; + options = options || {}; + + if (type === 'dir') { + mime = mime || 'httpd/unix-directory'; + } //containing tr var tr = $('<tr></tr>').attr({ + "data-id" : fileData.id, "data-type": type, - "data-size": size, + "data-size": fileData.size, "data-file": name, - "data-permissions": permissions + "data-mime": mime, + "data-mtime": mtime, + "data-etag": fileData.etag, + "data-permissions": fileData.permissions || this.getDirectoryPermissions() }); + + if (type === 'dir') { + // use default folder icon + icon = icon || OC.imagePath('core', 'filetypes/folder'); + } + else { + icon = icon || OC.imagePath('core', 'filetypes/file'); + } + // filename td td = $('<td></td>').attr({ - "class": "filename svg", - "style": 'background-image:url('+iconurl+'); background-size: 32px;' + "class": "filename", + "style": 'background-image:url(' + icon + '); background-size: 32px;' }); - var rand = Math.random().toString(16).slice(2); - td.append('<input id="select-'+rand+'" type="checkbox" /><label for="select-'+rand+'"></label>'); + + // linkUrl + if (type === 'dir') { + linkUrl = FileList.linkTo(FileList.getCurrentDirectory() + '/' + name); + } + else { + linkUrl = Files.getDownloadUrl(name, FileList.getCurrentDirectory()); + } + td.append('<input id="select-' + fileData.id + '" type="checkbox" /><label for="select-' + fileData.id + '"></label>'); var link_elem = $('<a></a>').attr({ "class": "name", - "href": linktarget + "href": linkUrl }); - //split extension from filename for non dirs + + // from here work on the display name + name = fileData.displayName || name; + + // split extension from filename for non dirs if (type !== 'dir' && name.indexOf('.') !== -1) { - basename=name.substr(0,name.lastIndexOf('.')); - extension=name.substr(name.lastIndexOf('.')); + basename = name.substr(0, name.lastIndexOf('.')); + extension = name.substr(name.lastIndexOf('.')); } else { - basename=name; - extension=false; + basename = name; + extension = false; } var name_span=$('<span></span>').addClass('nametext').text(basename); link_elem.append(name_span); if (extension) { name_span.append($('<span></span>').addClass('extension').text(extension)); } - //dirs can show the number of uploaded files + // dirs can show the number of uploaded files if (type === 'dir') { link_elem.append($('<span></span>').attr({ 'class': 'uploadtext', @@ -103,99 +259,123 @@ window.FileList={ td.append(link_elem); tr.append(td); - //size column - if (size !== t('files', 'Pending')) { - simpleSize = humanFileSize(size); + // size column + if (typeof(fileData.size) !== 'undefined' && fileData.size >= 0) { + simpleSize = humanFileSize(parseInt(fileData.size, 10)); + sizeColor = Math.round(160-Math.pow((fileData.size/(1024*1024)),2)); } else { - simpleSize=t('files', 'Pending'); + simpleSize = t('files', 'Pending'); } - var sizeColor = Math.round(160-Math.pow((size/(1024*1024)),2)); - var lastModifiedTime = Math.round(lastModified.getTime() / 1000); + var lastModifiedTime = Math.round(mtime / 1000); td = $('<td></td>').attr({ "class": "filesize", - "style": 'color:rgb('+sizeColor+','+sizeColor+','+sizeColor+')' + "style": 'color:rgb(' + sizeColor + ',' + sizeColor + ',' + sizeColor + ')' }).text(simpleSize); tr.append(td); // date column - var modifiedColor = Math.round((Math.round((new Date()).getTime() / 1000)-lastModifiedTime)/60/60/24*5); + var modifiedColor = Math.round((Math.round((new Date()).getTime() / 1000) - mtime)/60/60/24*5); td = $('<td></td>').attr({ "class": "date" }); td.append($('<span></span>').attr({ "class": "modified", - "title": formatDate(lastModified), + "title": formatDate(mtime), "style": 'color:rgb('+modifiedColor+','+modifiedColor+','+modifiedColor+')' - }).text( relative_modified_date(lastModified.getTime() / 1000) )); + }).text( relative_modified_date(mtime / 1000) )); + tr.find('.filesize').text(simpleSize); tr.append(td); return tr; }, - addFile:function(name, size, lastModified, loading, hidden, param) { - var imgurl; + /** + * Adds an entry to the files table using the data from the given file data + * @param fileData map of file attributes + * @param options map of attributes: + * - "insert" true to insert in a sorted manner, false to append (default) + * - "updateSummary" true to update the summary after adding (default), false otherwise + * @return new tr element (not appended to the table) + */ + add: function(fileData, options) { + options = options || {}; + var type = fileData.type || 'file', + mime = fileData.mimetype, + permissions = parseInt(fileData.permissions, 10) || 0; - if (!param) { - param = {}; + if (type === 'dir') { + mime = mime || 'httpd/unix-directory'; } + var tr = this._createRow( + fileData, + options + ); + var filenameTd = tr.find('td.filename'); - var download_url = null; - if (!param.download_url) { - download_url = OC.generateUrl( - 'apps/files/download{file}', - { file: $('#dir').val()+'/'+name }); - } else { - download_url = param.download_url; + // sorted insert is expensive, so needs to be explicitly + // requested + if (options.insert) { + this.insertElement(fileData.name, type, tr); } + else { + this.$fileList.append(tr); + } + FileList.isEmpty = false; - if (loading) { - imgurl = OC.imagePath('core', 'loading.gif'); - } else { - imgurl = OC.imagePath('core', 'filetypes/file'); - } - var tr = this.createRow( - 'file', - name, - imgurl, - download_url, - size, - lastModified, - $('#permissions').val() - ); + // TODO: move dragging to FileActions ? + // enable drag only for deletable files + if (permissions & OC.PERMISSION_DELETE) { + filenameTd.draggable(dragOptions); + } + // allow dropping on folders + if (fileData.type === 'dir') { + filenameTd.droppable(folderDropOptions); + } - FileList.insertElement(name, 'file', tr); - if (loading) { - tr.data('loading', true); - } else { - tr.find('td.filename').draggable(dragOptions); + if (options.hidden) { + tr.addClass('hidden'); } - if (hidden) { - tr.hide(); + + // display actions + FileActions.display(filenameTd, false); + + if (fileData.isPreviewAvailable) { + // lazy load / newly inserted td ? + if (!fileData.icon) { + Files.lazyLoadPreview(getPathForPreview(fileData.name), mime, function(url) { + filenameTd.css('background-image', 'url(' + url + ')'); + }, null, null, fileData.etag); + } + else { + // set the preview URL directly + var urlSpec = { + file: FileList.getCurrentDirectory() + '/' + fileData.name, + c: fileData.etag + }; + var previewUrl = Files.generatePreviewUrl(urlSpec); + previewUrl = previewUrl.replace('(', '%28').replace(')', '%29'); + filenameTd.css('background-image', 'url(' + previewUrl + ')'); + } } - return tr; - }, - addDir:function(name, size, lastModified, hidden) { - - var tr = this.createRow( - 'dir', - name, - OC.imagePath('core', 'filetypes/folder'), - OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent($('#dir').val()+'/'+name).replace(/%2F/g, '/'), - size, - lastModified, - $('#permissions').val() - ); - FileList.insertElement(name, 'dir', tr); - var td = tr.find('td.filename'); - td.draggable(dragOptions); - td.droppable(folderDropOptions); - if (hidden) { - tr.hide(); + // defaults to true if not defined + if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) { + this.updateFileSummary(); + this.updateEmptyContent(); } - FileActions.display(tr.find('td.filename'), true); return tr; }, + /** + * Returns the current directory + * @return current directory + */ getCurrentDirectory: function(){ return $('#dir').val() || '/'; }, /** + * Returns the directory permissions + * @return permission value as integer + */ + getDirectoryPermissions: function() { + return parseInt($('#permissions').val(), 10); + }, + /** * @brief Changes the current directory and reload the file list. * @param targetDir target directory (non URL encoded) * @param changeUrl false if the URL must not be changed (defaults to true) @@ -209,7 +389,7 @@ window.FileList={ if (!force && currentDir === targetDir) { return; } - FileList.setCurrentDir(targetDir, changeUrl); + FileList._setCurrentDir(targetDir, changeUrl); $('#fileList').trigger( jQuery.Event('changeDirectory', { dir: targetDir, @@ -221,7 +401,13 @@ window.FileList={ linkTo: function(dir) { return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/'); }, - setCurrentDir: function(targetDir, changeUrl) { + + /** + * Sets the current directory name and updates the breadcrumb. + * @param targetDir directory to display + * @param changeUrl true to also update the URL, false otherwise (default) + */ + _setCurrentDir: function(targetDir, changeUrl) { var url, baseDir = OC.basename(targetDir); @@ -243,6 +429,7 @@ window.FileList={ window.location.hash = '?dir='+ encodeURIComponent(targetDir).replace(/%2F/g, '/'); } } + this.breadcrumb.setDirectory(this.getCurrentDirectory()); }, /** * @brief Reloads the file list using ajax call @@ -253,10 +440,9 @@ window.FileList={ FileList._reloadCall.abort(); } FileList._reloadCall = $.ajax({ - url: OC.filePath('files','ajax','list.php'), + url: Files.getAjaxUrl('list'), data: { - dir : $('#dir').val(), - breadcrumb: true + dir : $('#dir').val() }, error: function(result) { FileList.reloadCallback(result); @@ -269,8 +455,8 @@ window.FileList={ reloadCallback: function(result) { var $controls = $('#controls'); - delete FileList._reloadCall; - FileList.hideMask(); + delete this._reloadCall; + this.hideMask(); if (!result || result.status === 'error') { OC.Notification.show(result.data.message); @@ -279,7 +465,11 @@ window.FileList={ if (result.status === 404) { // go back home - FileList.changeDirectory('/'); + this.changeDirectory('/'); + return; + } + // aborted ? + if (result.status === 0){ return; } @@ -288,24 +478,10 @@ window.FileList={ Files.updateStorageStatistics(true); if (result.data.permissions) { - FileList.setDirectoryPermissions(result.data.permissions); - } - - if (typeof(result.data.breadcrumb) !== 'undefined') { - $controls.find('.crumb').remove(); - $controls.prepend(result.data.breadcrumb); - - var width = $(window).width(); - Files.initBreadCrumbs(); - Files.resizeBreadcrumbs(width, true); - - // in case svg is not supported by the browser we need to execute the fallback mechanism - if (!SVGSupport()) { - replaceSVG(); - } + this.setDirectoryPermissions(result.data.permissions); } - FileList.update(result.data.files); + this.setFiles(result.data.files); }, setDirectoryPermissions: function(permissions) { var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; @@ -322,10 +498,14 @@ window.FileList={ $('.actions,#file_action_panel').toggleClass('hidden', !show); if (show){ // make sure to display according to permissions - var permissions = $('#permissions').val(); + var permissions = this.getDirectoryPermissions(); var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; $('.creatable').toggleClass('hidden', !isCreatable); $('.notCreatable').toggleClass('hidden', isCreatable); + // remove old style breadcrumbs (some apps might create them) + $('#controls .crumb').remove(); + // refresh breadcrumbs in case it was replaced by an app + this.breadcrumb.render(); } else{ $('.creatable, .notCreatable').addClass('hidden'); @@ -341,22 +521,32 @@ window.FileList={ this.showActions(!show); $('#filestable').toggleClass('hidden', show); }, - remove:function(name){ + /** + * Removes a file entry from the list + * @param name name of the file to remove + * @param options optional options as map: + * "updateSummary": true to update the summary (default), false otherwise + */ + remove:function(name, options){ + options = options || {}; var fileEl = FileList.findFileEl(name); if (fileEl.data('permissions') & OC.PERMISSION_DELETE) { // file is only draggable when delete permissions are set fileEl.find('td.filename').draggable('destroy'); } fileEl.remove(); - FileList.updateFileSummary(); - if ( ! $('tr[data-file]').exists() ) { - $('#emptycontent').removeClass('hidden'); - $('#filescontent th').addClass('hidden'); + // TODO: improve performance on batch update + FileList.isEmpty = !this.$fileList.find('tr:not(.summary)').length; + if (typeof(options.updateSummary) === 'undefined' || !!options.updateSummary) { + FileList.updateEmptyContent(); + FileList.updateFileSummary(); } + return fileEl; }, insertElement:function(name, type, element) { - //find the correct spot to insert the file or folder - var pos, fileElements=$('tr[data-file][data-type="'+type+'"]:visible'); + // find the correct spot to insert the file or folder + var pos, + fileElements = this.$fileList.find('tr[data-file][data-type="'+type+'"]:not(.hidden)'); if (name.localeCompare($(fileElements[0]).attr('data-file')) < 0) { pos = -1; } else if (name.localeCompare($(fileElements[fileElements.length-1]).attr('data-file')) > 0) { @@ -376,35 +566,18 @@ window.FileList={ } else { $(fileElements[pos]).after(element); } - } else if (type === 'dir' && $('tr[data-file]').exists()) { - $('tr[data-file]').first().before(element); - } else if (type === 'file' && $('tr[data-file]').exists()) { - $('tr[data-file]').last().before(element); + } else if (type === 'dir' && !FileList.isEmpty) { + this.$fileList.find('tr[data-file]:first').before(element); + } else if (type === 'file' && !FileList.isEmpty) { + this.$fileList.find('tr[data-file]:last').before(element); } else { - $('#fileList').append(element); + this.$fileList.append(element); } - $('#emptycontent').addClass('hidden'); - $('#filestable th').removeClass('hidden'); + FileList.isEmpty = false; + FileList.updateEmptyContent(); FileList.updateFileSummary(); }, - loadingDone:function(name, id) { - var mime, tr = FileList.findFileEl(name); - tr.data('loading', false); - mime = tr.data('mime'); - tr.attr('data-mime', mime); - if (id) { - tr.attr('data-id', id); - } - var path = getPathForPreview(name); - Files.lazyLoadPreview(path, mime, function(previewpath) { - tr.find('td.filename').attr('style','background-image:url('+previewpath+')'); - }, null, null, tr.attr('data-etag')); - tr.find('td.filename').draggable(dragOptions); - }, - isLoading:function(file) { - return FileList.findFileEl(file).data('loading'); - }, - rename:function(oldname) { + rename: function(oldname) { var tr, td, input, form; tr = FileList.findFileEl(oldname); tr.data('renaming',true); @@ -438,6 +611,7 @@ window.FileList={ event.preventDefault(); try { var newname = input.val(); + var directory = FileList.getCurrentDirectory(); if (newname !== oldname) { checkInput(); // save background image, because it's replaced by a spinner while async request @@ -480,12 +654,12 @@ window.FileList={ tr.attr('data-mime', fileInfo.mime); tr.attr('data-etag', fileInfo.etag); if (fileInfo.isPreviewAvailable) { - Files.lazyLoadPreview(fileInfo.directory + '/' + fileInfo.name, result.data.mime, function(previewpath) { + Files.lazyLoadPreview(directory + '/' + fileInfo.name, result.data.mime, function(previewpath) { tr.find('td.filename').attr('style','background-image:url('+previewpath+')'); }, null, null, result.data.etag); } else { - tr.find('td.filename').removeClass('preview').attr('style','background-image:url('+fileInfo.icon+')'); + tr.find('td.filename').removeClass('preview').attr('style','background-image:url('+FileList._replaceSVG(fileInfo.icon)+')'); } } // reinsert row @@ -554,58 +728,12 @@ window.FileList={ inList:function(file) { return FileList.findFileEl(file).length; }, - replace:function(oldName, newName, isNewFile) { - // Finish any existing actions - var oldFileEl = FileList.findFileEl(oldName); - var newFileEl = FileList.findFileEl(newName); - oldFileEl.hide(); - newFileEl.hide(); - var tr = oldFileEl.clone(); - tr.attr('data-replace', 'true'); - tr.attr('data-file', newName); - var td = tr.children('td.filename'); - td.children('a.name .span').text(newName); - var path = td.children('a.name').attr('href'); - td.children('a.name').attr('href', path.replace(encodeURIComponent(oldName), encodeURIComponent(newName))); - var basename = newName; - if (newName.indexOf('.') > 0) { - basename = newName.substr(0, newName.lastIndexOf('.')); - } - td.children('a.name').empty(); - var span = $('<span class="nametext"></span>'); - span.text(basename); - td.children('a.name').append(span); - if (newName.indexOf('.') > 0) { - span.append($('<span class="extension">'+newName.substr(newName.lastIndexOf('.'))+'</span>')); - } - FileList.insertElement(newName, tr.data('type'), tr); - tr.show(); - FileList.replaceCanceled = false; - FileList.replaceOldName = oldName; - FileList.replaceNewName = newName; - FileList.replaceIsNewFile = isNewFile; - FileList.lastAction = function() { - FileList.finishReplace(); - }; - if (!isNewFile) { - OC.Notification.showHtml(t('files', 'replaced {new_name} with {old_name}', {new_name: newName}, {old_name: oldName})+'<span class="undo">'+t('files', 'undo')+'</span>'); - } - }, - finishReplace:function() { - if (!FileList.replaceCanceled && FileList.replaceOldName && FileList.replaceNewName) { - $.ajax({url: OC.filePath('files', 'ajax', 'rename.php'), async: false, data: { dir: $('#dir').val(), newname: FileList.replaceNewName, file: FileList.replaceOldName }, success: function(result) { - if (result && result.status === 'success') { - $('tr[data-replace="true"').removeAttr('data-replace'); - } else { - OC.dialogs.alert(result.data.message, 'Error moving file'); - } - FileList.replaceCanceled = true; - FileList.replaceOldName = null; - FileList.replaceNewName = null; - FileList.lastAction = null; - }}); - } - }, + /** + * Delete the given files from the given dir + * @param files file names list (without path) + * @param dir directory in which to delete the files, defaults to the current + * directory + */ do_delete:function(files, dir) { var params; if (files && files.substr) { @@ -622,7 +750,7 @@ window.FileList={ FileList.lastAction(); } - var params = { + params = { dir: dir || FileList.getCurrentDirectory() }; if (files) { @@ -643,10 +771,9 @@ window.FileList={ } else { $.each(files,function(index,file) { - var files = FileList.findFileEl(file); - files.remove(); - files.find('input[type="checkbox"]').removeAttr('checked'); - files.removeClass('selected'); + var fileEl = FileList.remove(file, {updateSummary: false}); + fileEl.find('input[type="checkbox"]').prop('checked', false); + fileEl.removeClass('selected'); }); } procesSelection(); @@ -680,7 +807,7 @@ window.FileList={ }); }, createFileSummary: function() { - if( $('#fileList tr').exists() ) { + if ( !FileList.isEmpty ) { var summary = this._calculateFileSummary(); // Get translations @@ -702,7 +829,7 @@ window.FileList={ } var $summary = $('<tr class="summary" data-file="undefined"><td><span class="info">'+info+'</span></td>'+fileSize+'<td></td></tr>'); - $('#fileList').append($summary); + this.$fileList.append($summary); var $dirInfo = $summary.find('.dirinfo'); var $fileInfo = $summary.find('.fileinfo'); @@ -710,12 +837,12 @@ window.FileList={ // Show only what's necessary, e.g.: no files: don't show "0 files" if (summary.totalDirs === 0) { - $dirInfo.hide(); - $connector.hide(); + $dirInfo.addClass('hidden'); + $connector.addClass('hidden'); } if (summary.totalFiles === 0) { - $fileInfo.hide(); - $connector.hide(); + $fileInfo.addClass('hidden'); + $connector.addClass('hidden'); } } }, @@ -740,10 +867,13 @@ window.FileList={ return result; }, updateFileSummary: function() { - var $summary = $('.summary'); + var $summary = this.$el.find('.summary'); + + // always make it the last element + this.$fileList.append($summary.detach()); // Check if we should remove the summary to show "Upload something" - if ($('#fileList tr').length === 1 && $summary.length === 1) { + if (this.isEmpty && $summary.length === 1) { $summary.remove(); } // If there's no summary create one (createFileSummary checks if there's data) @@ -751,7 +881,7 @@ window.FileList={ FileList.createFileSummary(); } // There's a summary and data -> Update the summary - else if ($('#fileList tr').length > 1 && $summary.length === 1) { + else if (!this.isEmpty && $summary.length === 1) { var fileSummary = this._calculateFileSummary(); var $dirInfo = $('.summary .dirinfo'); var $fileInfo = $('.summary .fileinfo'); @@ -764,19 +894,19 @@ window.FileList={ // Show only what's necessary (may be hidden) if (fileSummary.totalDirs === 0) { - $dirInfo.hide(); - $connector.hide(); + $dirInfo.addClass('hidden'); + $connector.addClass('hidden'); } else { - $dirInfo.show(); + $dirInfo.removeClass('hidden'); } if (fileSummary.totalFiles === 0) { - $fileInfo.hide(); - $connector.hide(); + $fileInfo.addClass('hidden'); + $connector.addClass('hidden'); } else { - $fileInfo.show(); + $fileInfo.removeClass('hidden'); } if (fileSummary.totalDirs > 0 && fileSummary.totalFiles > 0) { - $connector.show(); + $connector.removeClass('hidden'); } } }, @@ -784,10 +914,14 @@ window.FileList={ var $fileList = $('#fileList'); var permissions = $('#permissions').val(); var isCreatable = (permissions & OC.PERMISSION_CREATE) !== 0; - var exists = $fileList.find('tr:first').exists(); - $('#emptycontent').toggleClass('hidden', !isCreatable || exists); - $('#filestable th').toggleClass('hidden', !exists); + $('#emptycontent').toggleClass('hidden', !isCreatable || !FileList.isEmpty); + $('#filestable thead th').toggleClass('hidden', FileList.isEmpty); }, + /** + * Shows the loading mask. + * + * @see #hideMask + */ showMask: function() { // in case one was shown before var $mask = $('#content .mask'); @@ -795,23 +929,23 @@ window.FileList={ return; } + this.$el.addClass('hidden'); + $mask = $('<div class="mask transparent"></div>'); $mask.css('background-image', 'url('+ OC.imagePath('core', 'loading.gif') + ')'); $mask.css('background-repeat', 'no-repeat'); $('#content').append($mask); - // block UI, but only make visible in case loading takes longer - FileList._maskTimeout = window.setTimeout(function() { - // reset opacity - $mask.removeClass('transparent'); - }, 250); + $mask.removeClass('transparent'); }, + /** + * Hide the loading mask. + * @see #showMask + */ hideMask: function() { - var $mask = $('#content .mask').remove(); - if (FileList._maskTimeout) { - window.clearTimeout(FileList._maskTimeout); - } + $('#content .mask').remove(); + this.$el.removeClass('hidden'); }, scrollTo:function(file) { //scroll to and highlight preselected file @@ -850,29 +984,11 @@ window.FileList={ */ isAllSelected: function() { return $('#select_all').prop('checked'); - }, - - /** - * Returns the download URL of the given file - * @param filename file name of the file - * @param dir optional directory in which the file name is, defaults to the current directory - */ - getDownloadUrl: function(filename, dir) { - var files = filename; - if ($.isArray(filename)) { - files = JSON.stringify(filename); - } - var params = { - dir: dir || FileList.getCurrentDirectory(), - files: files - }; - return OC.filePath('files', 'ajax', 'download.php') + '?' + OC.buildQueryString(params); } }; $(document).ready(function() { - var baseDir, - isPublic = !!$('#isPublic').val(); + FileList.initialize(); // handle upload events var file_upload_start = $('#file_upload_start'); @@ -907,8 +1023,13 @@ $(document).ready(function() { {name: 'requesttoken', value: oc_requesttoken} ]; }; + } else { + // cancel uploads to current dir if no permission + var isCreatable = (FileList.getDirectoryPermissions() & OC.PERMISSION_CREATE) !== 0; + if (!isCreatable) { + return false; + } } - }); file_upload_start.on('fileuploadadd', function(e, data) { OC.Upload.log('filelist handle fileuploadadd', e, data); @@ -993,31 +1114,11 @@ $(document).ready(function() { if (data.files[0].size>=0) { size=data.files[0].size; } - var date=new Date(); - var param = {}; - if ($('#publicUploadRequestToken').exists()) { - param.download_url = document.location.href + '&download&path=/' + $('#dir').val() + '/' + file.name; - } //should the file exist in the list remove it FileList.remove(file.name); // create new file context - data.context = FileList.addFile(file.name, file.size, date, false, false, param); - - // update file data - data.context.attr('data-mime',file.mime).attr('data-id',file.id).attr('data-etag', file.etag); - - var permissions = data.context.data('permissions'); - if (permissions !== file.permissions) { - data.context.attr('data-permissions', file.permissions); - data.context.data('permissions', file.permissions); - } - FileActions.display(data.context.find('td.filename'), true); - - var path = getPathForPreview(file.name); - Files.lazyLoadPreview(path, file.mime, function(previewpath) { - data.context.find('td.filename').attr('style','background-image:url('+previewpath+')'); - }, null, null, file.etag); + data.context = FileList.add(file, {insert: true}); } } }); @@ -1049,31 +1150,6 @@ $(document).ready(function() { }); $('#notification').hide(); - $('#notification').on('click', '.undo', function() { - if (FileList.deleteFiles) { - $.each(FileList.deleteFiles,function(index,file) { - FileList.findFileEl(file).show(); - }); - FileList.deleteCanceled=true; - FileList.deleteFiles=null; - } else if (FileList.replaceOldName && FileList.replaceNewName) { - if (FileList.replaceIsNewFile) { - // Delete the new uploaded file - FileList.deleteCanceled = false; - FileList.deleteFiles = [FileList.replaceOldName]; - } else { - FileList.findFileEl(FileList.replaceOldName).show(); - } - $('tr[data-replace="true"').remove(); - FileList.findFileEl(FileList.replaceNewName).show(); - FileList.replaceCanceled = true; - FileList.replaceOldName = null; - FileList.replaceNewName = null; - FileList.replaceIsNewFile = null; - } - FileList.lastAction = null; - OC.Notification.hide(); - }); $('#notification:first-child').on('click', '.replace', function() { OC.Notification.hide(function() { FileList.replace($('#notification > span').attr('data-oldName'), $('#notification > span').attr('data-newName'), $('#notification > span').attr('data-isNewFile')); @@ -1081,7 +1157,7 @@ $(document).ready(function() { }); $('#notification:first-child').on('click', '.suggest', function() { var file = $('#notification > span').attr('data-oldName'); - FileList.findFileEl(file).show(); + FileList.findFileEl(file).removeClass('hidden'); OC.Notification.hide(); }); $('#notification:first-child').on('click', '.cancel', function() { @@ -1130,34 +1206,32 @@ $(document).ready(function() { } // disable ajax/history API for public app (TODO: until it gets ported) - if (!isPublic) { - // fallback to hashchange when no history support - if (!window.history.pushState) { - $(window).on('hashchange', function() { - FileList.changeDirectory(parseCurrentDirFromUrl(), false); - }); + // fallback to hashchange when no history support + if (!window.history.pushState) { + $(window).on('hashchange', function() { + FileList.changeDirectory(parseCurrentDirFromUrl(), false); + }); + } + window.onpopstate = function(e) { + var targetDir; + if (e.state && e.state.dir) { + targetDir = e.state.dir; } - window.onpopstate = function(e) { - var targetDir; - if (e.state && e.state.dir) { - targetDir = e.state.dir; - } - else{ - // read from URL - targetDir = parseCurrentDirFromUrl(); - } - if (targetDir) { - FileList.changeDirectory(targetDir, false); - } - }; - - if (parseInt($('#ajaxLoad').val(), 10) === 1) { - // need to initially switch the dir to the one from the hash (IE8) - FileList.changeDirectory(parseCurrentDirFromUrl(), false, true); + else{ + // read from URL + targetDir = parseCurrentDirFromUrl(); + } + if (targetDir) { + FileList.changeDirectory(targetDir, false); } + }; - FileList.setCurrentDir(parseCurrentDirFromUrl(), false); - } + var dir = parseCurrentDirFromUrl(); + // trigger ajax load, deferred to let sub-apps do their overrides first + setTimeout(function() { + FileList.changeDirectory(dir, false, true); + }, 0); FileList.createFileSummary(); }); + |