mirror of
https://github.com/nextcloud/server.git
synced 2026-04-05 17:16:55 -04:00
Merge pull request #7167 from owncloud/files-ajaxload-infscroll
Infinite scrolling for files app
This commit is contained in:
commit
e055a411ea
19 changed files with 1740 additions and 769 deletions
|
|
@ -310,7 +310,6 @@ a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; }
|
|||
|
||||
/* Actions for selected files */
|
||||
.selectedActions {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
right: 0;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ OCP\Util::addscript('files', 'file-upload');
|
|||
OCP\Util::addscript('files', 'jquery.iframe-transport');
|
||||
OCP\Util::addscript('files', 'jquery.fileupload');
|
||||
OCP\Util::addscript('files', 'jquery-visibility');
|
||||
OCP\Util::addscript('files', 'filesummary');
|
||||
OCP\Util::addscript('files', 'breadcrumb');
|
||||
OCP\Util::addscript('files', 'filelist');
|
||||
|
||||
|
|
|
|||
|
|
@ -606,7 +606,7 @@ OC.Upload = {
|
|||
{dir:$('#dir').val(), filename:name},
|
||||
function(result) {
|
||||
if (result.status === 'success') {
|
||||
FileList.add(result.data, {hidden: hidden, insert: true});
|
||||
FileList.add(result.data, {hidden: hidden, animate: true});
|
||||
} else {
|
||||
OC.dialogs.alert(result.data.message, t('core', 'Could not create file'));
|
||||
}
|
||||
|
|
@ -619,7 +619,7 @@ OC.Upload = {
|
|||
{dir:$('#dir').val(), foldername:name},
|
||||
function(result) {
|
||||
if (result.status === 'success') {
|
||||
FileList.add(result.data, {hidden: hidden, insert: true});
|
||||
FileList.add(result.data, {hidden: hidden, animate: true});
|
||||
} else {
|
||||
OC.dialogs.alert(result.data.message, t('core', 'Could not create folder'));
|
||||
}
|
||||
|
|
@ -657,7 +657,7 @@ OC.Upload = {
|
|||
var file = data;
|
||||
$('#uploadprogressbar').fadeOut();
|
||||
|
||||
FileList.add(file, {hidden: hidden, insert: true});
|
||||
FileList.add(file, {hidden: hidden, animate: true});
|
||||
});
|
||||
eventSource.listen('error',function(error) {
|
||||
$('#uploadprogressbar').fadeOut();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -8,8 +8,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* global OC, t, n, FileList, FileActions */
|
||||
/* global getURLParameter, isPublic */
|
||||
/* global OC, t, FileList */
|
||||
/* global getURLParameter */
|
||||
var Files = {
|
||||
// file space size sync
|
||||
_updateStorageStatistics: function() {
|
||||
|
|
@ -96,10 +96,10 @@ var Files = {
|
|||
throw t('files', 'File name cannot be empty.');
|
||||
}
|
||||
// check for invalid characters
|
||||
var invalid_characters =
|
||||
var invalidCharacters =
|
||||
['\\', '/', '<', '>', ':', '"', '|', '?', '*', '\n'];
|
||||
for (var i = 0; i < invalid_characters.length; i++) {
|
||||
if (trimmedName.indexOf(invalid_characters[i]) !== -1) {
|
||||
for (var i = 0; i < invalidCharacters.length; i++) {
|
||||
if (trimmedName.indexOf(invalidCharacters[i]) !== -1) {
|
||||
throw t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed.");
|
||||
}
|
||||
}
|
||||
|
|
@ -116,7 +116,8 @@ var Files = {
|
|||
return;
|
||||
}
|
||||
if (usedSpacePercent > 90) {
|
||||
OC.Notification.show(t('files', 'Your storage is almost full ({usedSpacePercent}%)', {usedSpacePercent: usedSpacePercent}));
|
||||
OC.Notification.show(t('files', 'Your storage is almost full ({usedSpacePercent}%)',
|
||||
{usedSpacePercent: usedSpacePercent}));
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -142,6 +143,7 @@ var Files = {
|
|||
}
|
||||
},
|
||||
|
||||
// TODO: move to FileList class
|
||||
setupDragAndDrop: function() {
|
||||
var $fileList = $('#fileList');
|
||||
|
||||
|
|
@ -209,7 +211,7 @@ $(document).ready(function() {
|
|||
// Trigger cancelling of file upload
|
||||
$('#uploadprogresswrapper .stop').on('click', function() {
|
||||
OC.Upload.cancelUploads();
|
||||
procesSelection();
|
||||
FileList.updateSelectionSummary();
|
||||
});
|
||||
|
||||
// Show trash bin
|
||||
|
|
@ -217,135 +219,11 @@ $(document).ready(function() {
|
|||
window.location=OC.filePath('files_trashbin', '', 'index.php');
|
||||
});
|
||||
|
||||
var lastChecked;
|
||||
|
||||
// Sets the file link behaviour :
|
||||
$('#fileList').on('click','td.filename a',function(event) {
|
||||
if (event.ctrlKey || event.shiftKey) {
|
||||
event.preventDefault();
|
||||
if (event.shiftKey) {
|
||||
var last = $(lastChecked).parent().parent().prevAll().length;
|
||||
var first = $(this).parent().parent().prevAll().length;
|
||||
var start = Math.min(first, last);
|
||||
var end = Math.max(first, last);
|
||||
var rows = $(this).parent().parent().parent().children('tr');
|
||||
for (var i = start; i < end; i++) {
|
||||
$(rows).each(function(index) {
|
||||
if (index === i) {
|
||||
var checkbox = $(this).children().children('input:checkbox');
|
||||
$(checkbox).attr('checked', 'checked');
|
||||
$(checkbox).parent().parent().addClass('selected');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
var checkbox = $(this).parent().children('input:checkbox');
|
||||
lastChecked = checkbox;
|
||||
if ($(checkbox).attr('checked')) {
|
||||
$(checkbox).removeAttr('checked');
|
||||
$(checkbox).parent().parent().removeClass('selected');
|
||||
$('#select_all').removeAttr('checked');
|
||||
} else {
|
||||
$(checkbox).attr('checked', 'checked');
|
||||
$(checkbox).parent().parent().toggleClass('selected');
|
||||
var selectedCount = $('td.filename input:checkbox:checked').length;
|
||||
if (selectedCount === $('td.filename input:checkbox').length) {
|
||||
$('#select_all').attr('checked', 'checked');
|
||||
}
|
||||
}
|
||||
procesSelection();
|
||||
} else {
|
||||
var filename=$(this).parent().parent().attr('data-file');
|
||||
var tr = FileList.findFileEl(filename);
|
||||
var renaming=tr.data('renaming');
|
||||
if (!renaming) {
|
||||
FileActions.currentFile = $(this).parent();
|
||||
var mime=FileActions.getCurrentMimeType();
|
||||
var type=FileActions.getCurrentType();
|
||||
var permissions = FileActions.getCurrentPermissions();
|
||||
var action=FileActions.getDefault(mime,type, permissions);
|
||||
if (action) {
|
||||
event.preventDefault();
|
||||
action(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Sets the select_all checkbox behaviour :
|
||||
$('#select_all').click(function() {
|
||||
if ($(this).attr('checked')) {
|
||||
// Check all
|
||||
$('td.filename input:checkbox').attr('checked', true);
|
||||
$('td.filename input:checkbox').parent().parent().addClass('selected');
|
||||
} else {
|
||||
// Uncheck all
|
||||
$('td.filename input:checkbox').attr('checked', false);
|
||||
$('td.filename input:checkbox').parent().parent().removeClass('selected');
|
||||
}
|
||||
procesSelection();
|
||||
});
|
||||
|
||||
$('#fileList').on('change', 'td.filename input:checkbox',function(event) {
|
||||
if (event.shiftKey) {
|
||||
var last = $(lastChecked).parent().parent().prevAll().length;
|
||||
var first = $(this).parent().parent().prevAll().length;
|
||||
var start = Math.min(first, last);
|
||||
var end = Math.max(first, last);
|
||||
var rows = $(this).parent().parent().parent().children('tr');
|
||||
for (var i = start; i < end; i++) {
|
||||
$(rows).each(function(index) {
|
||||
if (index === i) {
|
||||
var checkbox = $(this).children().children('input:checkbox');
|
||||
$(checkbox).attr('checked', 'checked');
|
||||
$(checkbox).parent().parent().addClass('selected');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
var selectedCount=$('td.filename input:checkbox:checked').length;
|
||||
$(this).parent().parent().toggleClass('selected');
|
||||
if (!$(this).attr('checked')) {
|
||||
$('#select_all').attr('checked',false);
|
||||
} else {
|
||||
if (selectedCount===$('td.filename input:checkbox').length) {
|
||||
$('#select_all').attr('checked',true);
|
||||
}
|
||||
}
|
||||
procesSelection();
|
||||
});
|
||||
|
||||
$('.download').click('click',function(event) {
|
||||
var files;
|
||||
var dir = FileList.getCurrentDirectory();
|
||||
if (FileList.isAllSelected()) {
|
||||
files = OC.basename(dir);
|
||||
dir = OC.dirname(dir) || '/';
|
||||
}
|
||||
else {
|
||||
files = Files.getSelectedFiles('name');
|
||||
}
|
||||
OC.Notification.show(t('files','Your download is being prepared. This might take some time if the files are big.'));
|
||||
OC.redirect(Files.getDownloadUrl(files, dir));
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.delete-selected').click(function(event) {
|
||||
var files = Files.getSelectedFiles('name');
|
||||
event.preventDefault();
|
||||
if (FileList.isAllSelected()) {
|
||||
files = null;
|
||||
}
|
||||
FileList.do_delete(files);
|
||||
return false;
|
||||
});
|
||||
|
||||
// drag&drop support using jquery.fileupload
|
||||
// TODO use OC.dialogs
|
||||
$(document).bind('drop dragover', function (e) {
|
||||
e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone
|
||||
});
|
||||
});
|
||||
|
||||
//do a background scan if needed
|
||||
scanFiles();
|
||||
|
|
@ -422,34 +300,22 @@ function scanFiles(force, dir, users) {
|
|||
}
|
||||
scanFiles.scanning=false;
|
||||
|
||||
function boolOperationFinished(data, callback) {
|
||||
result = jQuery.parseJSON(data.responseText);
|
||||
Files.updateMaxUploadFilesize(result);
|
||||
if (result.status === 'success') {
|
||||
callback.call();
|
||||
} else {
|
||||
alert(result.data.message);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move to FileList
|
||||
var createDragShadow = function(event) {
|
||||
//select dragged file
|
||||
var isDragSelected = $(event.target).parents('tr').find('td input:first').prop('checked');
|
||||
if (!isDragSelected) {
|
||||
//select dragged file
|
||||
$(event.target).parents('tr').find('td input:first').prop('checked',true);
|
||||
FileList._selectFileEl($(event.target).parents('tr:first'), true);
|
||||
}
|
||||
|
||||
var selectedFiles = Files.getSelectedFiles();
|
||||
// do not show drag shadow for too many files
|
||||
var selectedFiles = _.first(FileList.getSelectedFiles(), FileList.pageSize);
|
||||
selectedFiles.sort(FileList._fileInfoCompare);
|
||||
|
||||
if (!isDragSelected && selectedFiles.length === 1) {
|
||||
//revert the selection
|
||||
$(event.target).parents('tr').find('td input:first').prop('checked',false);
|
||||
}
|
||||
|
||||
//also update class when we dragged more than one file
|
||||
if (selectedFiles.length > 1) {
|
||||
$(event.target).parents('tr').addClass('selected');
|
||||
FileList._selectFileEl($(event.target).parents('tr:first'), false);
|
||||
}
|
||||
|
||||
// build dragshadow
|
||||
|
|
@ -460,9 +326,12 @@ var createDragShadow = function(event) {
|
|||
var dir=$('#dir').val();
|
||||
|
||||
$(selectedFiles).each(function(i,elem) {
|
||||
var newtr = $('<tr/>').attr('data-dir', dir).attr('data-filename', elem.name).attr('data-origin', elem.origin);
|
||||
var newtr = $('<tr/>')
|
||||
.attr('data-dir', dir)
|
||||
.attr('data-file', elem.name)
|
||||
.attr('data-origin', elem.origin);
|
||||
newtr.append($('<td/>').addClass('filename').text(elem.name));
|
||||
newtr.append($('<td/>').addClass('size').text(humanFileSize(elem.size)));
|
||||
newtr.append($('<td/>').addClass('size').text(OC.Util.humanFileSize(elem.size)));
|
||||
tbody.append(newtr);
|
||||
if (elem.type === 'dir') {
|
||||
newtr.find('td.filename').attr('style','background-image:url('+OC.imagePath('core', 'filetypes/folder.png')+')');
|
||||
|
|
@ -479,155 +348,58 @@ var createDragShadow = function(event) {
|
|||
|
||||
//options for file drag/drop
|
||||
//start&stop handlers needs some cleaning up
|
||||
// TODO: move to FileList class
|
||||
var dragOptions={
|
||||
revert: 'invalid', revertDuration: 300,
|
||||
opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: 24, top: 18 },
|
||||
helper: createDragShadow, cursor: 'move',
|
||||
start: function(event, ui){
|
||||
var $selectedFiles = $('td.filename input:checkbox:checked');
|
||||
if($selectedFiles.length > 1){
|
||||
$selectedFiles.parents('tr').fadeTo(250, 0.2);
|
||||
}
|
||||
else{
|
||||
$(this).fadeTo(250, 0.2);
|
||||
}
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
var $selectedFiles = $('td.filename input:checkbox:checked');
|
||||
if($selectedFiles.length > 1){
|
||||
$selectedFiles.parents('tr').fadeTo(250, 1);
|
||||
}
|
||||
else{
|
||||
$(this).fadeTo(250, 1);
|
||||
}
|
||||
$('#fileList tr td.filename').addClass('ui-draggable');
|
||||
start: function(event, ui){
|
||||
var $selectedFiles = $('td.filename input:checkbox:checked');
|
||||
if($selectedFiles.length > 1){
|
||||
$selectedFiles.parents('tr').fadeTo(250, 0.2);
|
||||
}
|
||||
else{
|
||||
$(this).fadeTo(250, 0.2);
|
||||
}
|
||||
},
|
||||
stop: function(event, ui) {
|
||||
var $selectedFiles = $('td.filename input:checkbox:checked');
|
||||
if($selectedFiles.length > 1){
|
||||
$selectedFiles.parents('tr').fadeTo(250, 1);
|
||||
}
|
||||
else{
|
||||
$(this).fadeTo(250, 1);
|
||||
}
|
||||
$('#fileList tr td.filename').addClass('ui-draggable');
|
||||
}
|
||||
};
|
||||
// sane browsers support using the distance option
|
||||
if ( $('html.ie').length === 0) {
|
||||
dragOptions['distance'] = 20;
|
||||
}
|
||||
|
||||
var folderDropOptions={
|
||||
// TODO: move to FileList class
|
||||
var folderDropOptions = {
|
||||
hoverClass: "canDrop",
|
||||
drop: function( event, ui ) {
|
||||
//don't allow moving a file into a selected folder
|
||||
// don't allow moving a file into a selected folder
|
||||
if ($(event.target).parents('tr').find('td input:first').prop('checked') === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var target = $(this).closest('tr').data('file');
|
||||
var targetPath = FileList.getCurrentDirectory() + '/' + $(this).closest('tr').data('file');
|
||||
|
||||
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: dir+'/'+target }, function(result) {
|
||||
if (result) {
|
||||
if (result.status === 'success') {
|
||||
//recalculate folder size
|
||||
var oldFile = FileList.findFileEl(target);
|
||||
var newFile = FileList.findFileEl(file);
|
||||
var oldSize = oldFile.data('size');
|
||||
var newSize = oldSize + newFile.data('size');
|
||||
oldFile.data('size', newSize);
|
||||
oldFile.find('td.filesize').text(humanFileSize(newSize));
|
||||
var files = FileList.getSelectedFiles();
|
||||
if (files.length === 0) {
|
||||
// single one selected without checkbox?
|
||||
files = _.map(ui.helper.find('tr'), FileList.elementToFile);
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
FileList.move(_.pluck(files, 'name'), targetPath);
|
||||
},
|
||||
tolerance: 'pointer'
|
||||
};
|
||||
|
||||
function procesSelection() {
|
||||
var selected = Files.getSelectedFiles();
|
||||
var selectedFiles = selected.filter(function(el) {
|
||||
return el.type==='file';
|
||||
});
|
||||
var selectedFolders = selected.filter(function(el) {
|
||||
return el.type==='dir';
|
||||
});
|
||||
if (selectedFiles.length === 0 && selectedFolders.length === 0) {
|
||||
$('#headerName span.name').text(t('files','Name'));
|
||||
$('#headerSize').text(t('files','Size'));
|
||||
$('#modified').text(t('files','Modified'));
|
||||
$('table').removeClass('multiselect');
|
||||
$('.selectedActions').hide();
|
||||
$('#select_all').removeAttr('checked');
|
||||
}
|
||||
else {
|
||||
$('.selectedActions').show();
|
||||
var totalSize = 0;
|
||||
for(var i=0; i<selectedFiles.length; i++) {
|
||||
totalSize+=selectedFiles[i].size;
|
||||
}
|
||||
for(var i=0; i<selectedFolders.length; i++) {
|
||||
totalSize+=selectedFolders[i].size;
|
||||
}
|
||||
$('#headerSize').text(humanFileSize(totalSize));
|
||||
var selection = '';
|
||||
if (selectedFolders.length > 0) {
|
||||
selection += n('files', '%n folder', '%n folders', selectedFolders.length);
|
||||
if (selectedFiles.length > 0) {
|
||||
selection += ' & ';
|
||||
}
|
||||
}
|
||||
if (selectedFiles.length>0) {
|
||||
selection += n('files', '%n file', '%n files', selectedFiles.length);
|
||||
}
|
||||
$('#headerName span.name').text(selection);
|
||||
$('#modified').text('');
|
||||
$('table').addClass('multiselect');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get a list of selected files
|
||||
* @param {string} property (option) the property of the file requested
|
||||
* @return {array}
|
||||
*
|
||||
* possible values for property: name, mime, size and type
|
||||
* if property is set, an array with that property for each file is returnd
|
||||
* if it's ommited an array of objects with all properties is returned
|
||||
*/
|
||||
Files.getSelectedFiles = function(property) {
|
||||
var elements=$('td.filename input:checkbox:checked').parent().parent();
|
||||
var files=[];
|
||||
elements.each(function(i,element) {
|
||||
var file={
|
||||
name:$(element).attr('data-file'),
|
||||
mime:$(element).data('mime'),
|
||||
type:$(element).data('type'),
|
||||
size:$(element).data('size'),
|
||||
etag:$(element).data('etag'),
|
||||
origin: $(element).data('id')
|
||||
};
|
||||
if (property) {
|
||||
files.push(file[property]);
|
||||
} else {
|
||||
files.push(file);
|
||||
}
|
||||
});
|
||||
return files;
|
||||
}
|
||||
|
||||
Files.getMimeIcon = function(mime, ready) {
|
||||
if (Files.getMimeIcon.cache[mime]) {
|
||||
ready(Files.getMimeIcon.cache[mime]);
|
||||
|
|
@ -665,7 +437,7 @@ Files.generatePreviewUrl = function(urlSpec) {
|
|||
urlSpec.x *= window.devicePixelRatio;
|
||||
urlSpec.forceIcon = 0;
|
||||
return OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
|
||||
}
|
||||
};
|
||||
|
||||
Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
|
||||
// get mime icon url
|
||||
|
|
|
|||
195
apps/files/js/filesummary.js
Normal file
195
apps/files/js/filesummary.js
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Vincent Petry
|
||||
* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global OC, n, t */
|
||||
|
||||
(function() {
|
||||
/**
|
||||
* The FileSummary class encapsulates the file summary values and
|
||||
* the logic to render it in the given container
|
||||
* @param $tr table row element
|
||||
* $param summary optional initial summary value
|
||||
*/
|
||||
var FileSummary = function($tr) {
|
||||
this.$el = $tr;
|
||||
this.clear();
|
||||
this.render();
|
||||
};
|
||||
|
||||
FileSummary.prototype = {
|
||||
summary: {
|
||||
totalFiles: 0,
|
||||
totalDirs: 0,
|
||||
totalSize: 0
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds file
|
||||
* @param file file to add
|
||||
* @param update whether to update the display
|
||||
*/
|
||||
add: function(file, update) {
|
||||
if (file.type === 'dir' || file.mime === 'httpd/unix-directory') {
|
||||
this.summary.totalDirs++;
|
||||
}
|
||||
else {
|
||||
this.summary.totalFiles++;
|
||||
}
|
||||
this.summary.totalSize += parseInt(file.size, 10) || 0;
|
||||
if (!!update) {
|
||||
this.update();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Removes file
|
||||
* @param file file to remove
|
||||
* @param update whether to update the display
|
||||
*/
|
||||
remove: function(file, update) {
|
||||
if (file.type === 'dir' || file.mime === 'httpd/unix-directory') {
|
||||
this.summary.totalDirs--;
|
||||
}
|
||||
else {
|
||||
this.summary.totalFiles--;
|
||||
}
|
||||
this.summary.totalSize -= parseInt(file.size, 10) || 0;
|
||||
if (!!update) {
|
||||
this.update();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Returns the total of files and directories
|
||||
*/
|
||||
getTotal: function() {
|
||||
return this.summary.totalDirs + this.summary.totalFiles;
|
||||
},
|
||||
/**
|
||||
* Recalculates the summary based on the given files array
|
||||
* @param files array of files
|
||||
*/
|
||||
calculate: function(files) {
|
||||
var file;
|
||||
var summary = {
|
||||
totalDirs: 0,
|
||||
totalFiles: 0,
|
||||
totalSize: 0
|
||||
};
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
file = files[i];
|
||||
if (file.type === 'dir' || file.mime === 'httpd/unix-directory') {
|
||||
summary.totalDirs++;
|
||||
}
|
||||
else {
|
||||
summary.totalFiles++;
|
||||
}
|
||||
summary.totalSize += parseInt(file.size, 10) || 0;
|
||||
}
|
||||
this.setSummary(summary);
|
||||
},
|
||||
/**
|
||||
* Clears the summary
|
||||
*/
|
||||
clear: function() {
|
||||
this.calculate([]);
|
||||
},
|
||||
/**
|
||||
* Sets the current summary values
|
||||
* @param summary map
|
||||
*/
|
||||
setSummary: function(summary) {
|
||||
this.summary = summary;
|
||||
this.update();
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders the file summary element
|
||||
*/
|
||||
update: function() {
|
||||
if (!this.$el) {
|
||||
return;
|
||||
}
|
||||
if (!this.summary.totalFiles && !this.summary.totalDirs) {
|
||||
this.$el.addClass('hidden');
|
||||
return;
|
||||
}
|
||||
// There's a summary and data -> Update the summary
|
||||
this.$el.removeClass('hidden');
|
||||
var $dirInfo = this.$el.find('.dirinfo');
|
||||
var $fileInfo = this.$el.find('.fileinfo');
|
||||
var $connector = this.$el.find('.connector');
|
||||
|
||||
// Substitute old content with new translations
|
||||
$dirInfo.html(n('files', '%n folder', '%n folders', this.summary.totalDirs));
|
||||
$fileInfo.html(n('files', '%n file', '%n files', this.summary.totalFiles));
|
||||
this.$el.find('.filesize').html(OC.Util.humanFileSize(this.summary.totalSize));
|
||||
|
||||
// Show only what's necessary (may be hidden)
|
||||
if (this.summary.totalDirs === 0) {
|
||||
$dirInfo.addClass('hidden');
|
||||
$connector.addClass('hidden');
|
||||
} else {
|
||||
$dirInfo.removeClass('hidden');
|
||||
}
|
||||
if (this.summary.totalFiles === 0) {
|
||||
$fileInfo.addClass('hidden');
|
||||
$connector.addClass('hidden');
|
||||
} else {
|
||||
$fileInfo.removeClass('hidden');
|
||||
}
|
||||
if (this.summary.totalDirs > 0 && this.summary.totalFiles > 0) {
|
||||
$connector.removeClass('hidden');
|
||||
}
|
||||
},
|
||||
render: function() {
|
||||
if (!this.$el) {
|
||||
return;
|
||||
}
|
||||
// TODO: ideally this should be separate to a template or something
|
||||
var summary = this.summary;
|
||||
var directoryInfo = n('files', '%n folder', '%n folders', summary.totalDirs);
|
||||
var fileInfo = n('files', '%n file', '%n files', summary.totalFiles);
|
||||
|
||||
var infoVars = {
|
||||
dirs: '<span class="dirinfo">'+directoryInfo+'</span><span class="connector">',
|
||||
files: '</span><span class="fileinfo">'+fileInfo+'</span>'
|
||||
};
|
||||
|
||||
// don't show the filesize column, if filesize is NaN (e.g. in trashbin)
|
||||
var fileSize = '';
|
||||
if (!isNaN(summary.totalSize)) {
|
||||
fileSize = '<td class="filesize">' + OC.Util.humanFileSize(summary.totalSize) + '</td>';
|
||||
}
|
||||
|
||||
var info = t('files', '{dirs} and {files}', infoVars);
|
||||
|
||||
var $summary = $('<td><span class="info">'+info+'</span></td>'+fileSize+'<td></td>');
|
||||
|
||||
if (!this.summary.totalFiles && !this.summary.totalDirs) {
|
||||
this.$el.addClass('hidden');
|
||||
}
|
||||
|
||||
this.$el.append($summary);
|
||||
}
|
||||
};
|
||||
window.FileSummary = FileSummary;
|
||||
})();
|
||||
|
||||
|
|
@ -91,6 +91,8 @@
|
|||
</thead>
|
||||
<tbody id="fileList">
|
||||
</tbody>
|
||||
<tfoot>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div id="editor"></div><!-- FIXME Do not use this div in your app! It is deprecated and will be removed in the future! -->
|
||||
<div id="uploadsize-message" title="<?php p($l->t('Upload too large'))?>">
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ describe('FileActions tests', function() {
|
|||
$body.append('<input type="hidden" id="permissions" value="31"></input>');
|
||||
// dummy files table
|
||||
$filesTable = $body.append('<table id="filestable"></table>');
|
||||
FileList.files = [];
|
||||
});
|
||||
afterEach(function() {
|
||||
$('#dir, #permissions, #filestable').remove();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,33 @@ describe('FileList tests', function() {
|
|||
var testFiles, alertStub, notificationStub,
|
||||
pushStateStub;
|
||||
|
||||
/**
|
||||
* Generate test file data
|
||||
*/
|
||||
function generateFiles(startIndex, endIndex) {
|
||||
var files = [];
|
||||
var name;
|
||||
for (var i = startIndex; i <= endIndex; i++) {
|
||||
name = 'File with index ';
|
||||
if (i < 10) {
|
||||
// do not rely on localeCompare here
|
||||
// and make the sorting predictable
|
||||
// cross-browser
|
||||
name += '0';
|
||||
}
|
||||
name += i + '.txt';
|
||||
files.push({
|
||||
id: i,
|
||||
type: 'file',
|
||||
name: name,
|
||||
mimetype: 'text/plain',
|
||||
size: i * 2,
|
||||
etag: 'abc'
|
||||
});
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
// init horrible parameters
|
||||
var $body = $('body');
|
||||
|
|
@ -48,9 +75,17 @@ describe('FileList tests', function() {
|
|||
' <div class="notCreatable"></div>' +
|
||||
'</div>' +
|
||||
// dummy table
|
||||
// TODO: at some point this will be rendered by the FileList class itself!
|
||||
'<table id="filestable">' +
|
||||
'<thead><tr><th class="hidden">Name</th></tr></thead>' +
|
||||
'<thead><tr><th id="headerName" class="hidden">' +
|
||||
'<input type="checkbox" id="select_all">' +
|
||||
'<span class="name">Name</span>' +
|
||||
'<span class="selectedActions hidden">' +
|
||||
'<a href class="download">Download</a>' +
|
||||
'<a href class="delete-selected">Delete</a></span>' +
|
||||
'</th></tr></thead>' +
|
||||
'<tbody id="fileList"></tbody>' +
|
||||
'<tfoot></tfoot>' +
|
||||
'</table>' +
|
||||
'<div id="emptycontent">Empty content message</div>'
|
||||
);
|
||||
|
|
@ -60,25 +95,29 @@ describe('FileList tests', function() {
|
|||
type: 'file',
|
||||
name: 'One.txt',
|
||||
mimetype: 'text/plain',
|
||||
size: 12
|
||||
size: 12,
|
||||
etag: 'abc'
|
||||
}, {
|
||||
id: 2,
|
||||
type: 'file',
|
||||
name: 'Two.jpg',
|
||||
mimetype: 'image/jpeg',
|
||||
size: 12049
|
||||
size: 12049,
|
||||
etag: 'def',
|
||||
}, {
|
||||
id: 3,
|
||||
type: 'file',
|
||||
name: 'Three.pdf',
|
||||
mimetype: 'application/pdf',
|
||||
size: 58009
|
||||
size: 58009,
|
||||
etag: '123',
|
||||
}, {
|
||||
id: 4,
|
||||
type: 'dir',
|
||||
name: 'somedir',
|
||||
mimetype: 'httpd/unix-directory',
|
||||
size: 250
|
||||
size: 250,
|
||||
etag: '456'
|
||||
}];
|
||||
|
||||
FileList.initialize();
|
||||
|
|
@ -220,25 +259,65 @@ describe('FileList tests', function() {
|
|||
var $tr = FileList.add(fileData);
|
||||
expect($tr.find('.filesize').text()).toEqual('0 B');
|
||||
});
|
||||
it('adds new file to the end of the list before the summary', function() {
|
||||
it('adds new file to the end of the list', function() {
|
||||
var $tr;
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'P comes after O.txt'
|
||||
name: 'ZZZ.txt'
|
||||
};
|
||||
FileList.setFiles(testFiles);
|
||||
$tr = FileList.add(fileData);
|
||||
expect($tr.index()).toEqual(4);
|
||||
expect($tr.next().hasClass('summary')).toEqual(true);
|
||||
});
|
||||
it('adds new file at correct position in insert mode', function() {
|
||||
it('inserts files in a sorted manner when insert option is enabled', function() {
|
||||
var $tr;
|
||||
for (var i = 0; i < testFiles.length; i++) {
|
||||
FileList.add(testFiles[i]);
|
||||
}
|
||||
expect(FileList.files[0].name).toEqual('somedir');
|
||||
expect(FileList.files[1].name).toEqual('One.txt');
|
||||
expect(FileList.files[2].name).toEqual('Three.pdf');
|
||||
expect(FileList.files[3].name).toEqual('Two.jpg');
|
||||
});
|
||||
it('inserts new file at correct position', function() {
|
||||
var $tr;
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'P comes after O.txt'
|
||||
};
|
||||
FileList.setFiles(testFiles);
|
||||
$tr = FileList.add(fileData, {insert: true});
|
||||
for (var i = 0; i < testFiles.length; i++) {
|
||||
FileList.add(testFiles[i]);
|
||||
}
|
||||
$tr = FileList.add(fileData);
|
||||
// after "One.txt"
|
||||
expect($tr.index()).toEqual(2);
|
||||
expect(FileList.files[2]).toEqual(fileData);
|
||||
});
|
||||
it('inserts new folder at correct position in insert mode', function() {
|
||||
var $tr;
|
||||
var fileData = {
|
||||
type: 'dir',
|
||||
name: 'somedir2 comes after somedir'
|
||||
};
|
||||
for (var i = 0; i < testFiles.length; i++) {
|
||||
FileList.add(testFiles[i]);
|
||||
}
|
||||
$tr = FileList.add(fileData);
|
||||
expect($tr.index()).toEqual(1);
|
||||
expect(FileList.files[1]).toEqual(fileData);
|
||||
});
|
||||
it('inserts new file at the end correctly', function() {
|
||||
var $tr;
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'zzz.txt'
|
||||
};
|
||||
for (var i = 0; i < testFiles.length; i++) {
|
||||
FileList.add(testFiles[i]);
|
||||
}
|
||||
$tr = FileList.add(fileData);
|
||||
expect($tr.index()).toEqual(4);
|
||||
expect(FileList.files[4]).toEqual(fileData);
|
||||
});
|
||||
it('removes empty content message and shows summary when adding first file', function() {
|
||||
var fileData = {
|
||||
|
|
@ -249,8 +328,8 @@ describe('FileList tests', function() {
|
|||
FileList.setFiles([]);
|
||||
expect(FileList.isEmpty).toEqual(true);
|
||||
FileList.add(fileData);
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(1);
|
||||
$summary = $('#filestable .summary');
|
||||
expect($summary.hasClass('hidden')).toEqual(false);
|
||||
// yes, ugly...
|
||||
expect($summary.find('.info').text()).toEqual('0 folders and 1 file');
|
||||
expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(true);
|
||||
|
|
@ -268,11 +347,12 @@ describe('FileList tests', function() {
|
|||
$removedEl = FileList.remove('One.txt');
|
||||
expect($removedEl).toBeDefined();
|
||||
expect($removedEl.attr('data-file')).toEqual('One.txt');
|
||||
expect($('#fileList tr:not(.summary)').length).toEqual(3);
|
||||
expect($('#fileList tr').length).toEqual(3);
|
||||
expect(FileList.files.length).toEqual(3);
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(1);
|
||||
$summary = $('#filestable .summary');
|
||||
expect($summary.hasClass('hidden')).toEqual(false);
|
||||
expect($summary.find('.info').text()).toEqual('1 folder and 2 files');
|
||||
expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false);
|
||||
expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false);
|
||||
|
|
@ -282,11 +362,12 @@ describe('FileList tests', function() {
|
|||
it('Shows empty content when removing last file', function() {
|
||||
FileList.setFiles([testFiles[0]]);
|
||||
FileList.remove('One.txt');
|
||||
expect($('#fileList tr:not(.summary)').length).toEqual(0);
|
||||
expect($('#fileList tr').length).toEqual(0);
|
||||
expect(FileList.files.length).toEqual(0);
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(0);
|
||||
$summary = $('#filestable .summary');
|
||||
expect($summary.hasClass('hidden')).toEqual(true);
|
||||
expect($('#filestable thead th').hasClass('hidden')).toEqual(true);
|
||||
expect($('#emptycontent').hasClass('hidden')).toEqual(false);
|
||||
expect(FileList.isEmpty).toEqual(true);
|
||||
|
|
@ -318,10 +399,10 @@ describe('FileList tests', function() {
|
|||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
expect(FileList.findFileEl('Two.jpg').length).toEqual(0);
|
||||
expect(FileList.findFileEl('Three.pdf').length).toEqual(1);
|
||||
expect(FileList.$fileList.find('tr:not(.summary)').length).toEqual(2);
|
||||
expect(FileList.$fileList.find('tr').length).toEqual(2);
|
||||
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(1);
|
||||
$summary = $('#filestable .summary');
|
||||
expect($summary.hasClass('hidden')).toEqual(false);
|
||||
expect($summary.find('.info').text()).toEqual('1 folder and 1 file');
|
||||
expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false);
|
||||
expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false);
|
||||
|
|
@ -342,11 +423,12 @@ describe('FileList tests', function() {
|
|||
JSON.stringify({status: 'success'})
|
||||
);
|
||||
|
||||
expect(FileList.$fileList.find('tr:not(.summary)').length).toEqual(0);
|
||||
expect(FileList.$fileList.find('tr').length).toEqual(0);
|
||||
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(0);
|
||||
$summary = $('#filestable .summary');
|
||||
expect($summary.hasClass('hidden')).toEqual(true);
|
||||
expect(FileList.isEmpty).toEqual(true);
|
||||
expect(FileList.files.length).toEqual(0);
|
||||
expect($('#filestable thead th').hasClass('hidden')).toEqual(true);
|
||||
expect($('#emptycontent').hasClass('hidden')).toEqual(false);
|
||||
});
|
||||
|
|
@ -363,7 +445,7 @@ describe('FileList tests', function() {
|
|||
// files are still in the list
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(1);
|
||||
expect(FileList.findFileEl('Two.jpg').length).toEqual(1);
|
||||
expect(FileList.$fileList.find('tr:not(.summary)').length).toEqual(4);
|
||||
expect(FileList.$fileList.find('tr').length).toEqual(4);
|
||||
|
||||
expect(notificationStub.calledOnce).toEqual(true);
|
||||
});
|
||||
|
|
@ -372,37 +454,41 @@ describe('FileList tests', function() {
|
|||
function doRename() {
|
||||
var $input, request;
|
||||
|
||||
FileList.setFiles(testFiles);
|
||||
for (var i = 0; i < testFiles.length; i++) {
|
||||
FileList.add(testFiles[i]);
|
||||
}
|
||||
|
||||
// trigger rename prompt
|
||||
FileList.rename('One.txt');
|
||||
$input = FileList.$fileList.find('input.filename');
|
||||
$input.val('One_renamed.txt').blur();
|
||||
$input.val('Tu_after_three.txt').blur();
|
||||
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
var request = fakeServer.requests[0];
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url.substr(0, request.url.indexOf('?'))).toEqual(OC.webroot + '/index.php/apps/files/ajax/rename.php');
|
||||
expect(OC.parseQueryString(request.url)).toEqual({'dir': '/subdir', newname: 'One_renamed.txt', file: 'One.txt'});
|
||||
expect(OC.parseQueryString(request.url)).toEqual({'dir': '/subdir', newname: 'Tu_after_three.txt', file: 'One.txt'});
|
||||
|
||||
// element is renamed before the request finishes
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
expect(FileList.findFileEl('One_renamed.txt').length).toEqual(1);
|
||||
expect(FileList.findFileEl('Tu_after_three.txt').length).toEqual(1);
|
||||
// input is gone
|
||||
expect(FileList.$fileList.find('input.filename').length).toEqual(0);
|
||||
}
|
||||
it('Keeps renamed file entry if rename ajax call suceeded', function() {
|
||||
it('Inserts renamed file entry at correct position if rename ajax call suceeded', function() {
|
||||
doRename();
|
||||
|
||||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'success',
|
||||
data: {
|
||||
name: 'One_renamed.txt'
|
||||
name: 'Tu_after_three.txt',
|
||||
type: 'file'
|
||||
}
|
||||
}));
|
||||
|
||||
// element stays renamed
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
expect(FileList.findFileEl('One_renamed.txt').length).toEqual(1);
|
||||
expect(FileList.findFileEl('Tu_after_three.txt').length).toEqual(1);
|
||||
expect(FileList.findFileEl('Tu_after_three.txt').index()).toEqual(2); // after Two.txt
|
||||
|
||||
expect(alertStub.notCalled).toEqual(true);
|
||||
});
|
||||
|
|
@ -418,7 +504,8 @@ describe('FileList tests', function() {
|
|||
|
||||
// element was reverted
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(1);
|
||||
expect(FileList.findFileEl('One_renamed.txt').length).toEqual(0);
|
||||
expect(FileList.findFileEl('One.txt').index()).toEqual(1); // after somedir
|
||||
expect(FileList.findFileEl('Tu_after_three.txt').length).toEqual(0);
|
||||
|
||||
expect(alertStub.calledOnce).toEqual(true);
|
||||
});
|
||||
|
|
@ -429,12 +516,12 @@ describe('FileList tests', function() {
|
|||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'success',
|
||||
data: {
|
||||
name: 'One_renamed.txt'
|
||||
name: 'Tu_after_three.txt'
|
||||
}
|
||||
}));
|
||||
|
||||
$tr = FileList.findFileEl('One_renamed.txt');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=One_renamed.txt');
|
||||
$tr = FileList.findFileEl('Tu_after_three.txt');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=Tu_after_three.txt');
|
||||
});
|
||||
// FIXME: fix this in the source code!
|
||||
xit('Correctly updates file link after rename when path has same name', function() {
|
||||
|
|
@ -446,27 +533,122 @@ describe('FileList tests', function() {
|
|||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'success',
|
||||
data: {
|
||||
name: 'One_renamed.txt'
|
||||
name: 'Tu_after_three.txt'
|
||||
}
|
||||
}));
|
||||
|
||||
$tr = FileList.findFileEl('One_renamed.txt');
|
||||
$tr = FileList.findFileEl('Tu_after_three.txt');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=One.txt');
|
||||
});
|
||||
});
|
||||
describe('Moving files', function() {
|
||||
beforeEach(function() {
|
||||
FileList.setFiles(testFiles);
|
||||
});
|
||||
it('Moves single file to target folder', function() {
|
||||
var request;
|
||||
FileList.move('One.txt', '/somedir');
|
||||
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/move.php');
|
||||
expect(OC.parseQueryString(request.requestBody)).toEqual({dir: '/subdir', file: 'One.txt', target: '/somedir'});
|
||||
|
||||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'success',
|
||||
data: {
|
||||
name: 'One.txt',
|
||||
type: 'file'
|
||||
}
|
||||
}));
|
||||
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
|
||||
// folder size has increased
|
||||
expect(FileList.findFileEl('somedir').data('size')).toEqual(262);
|
||||
expect(FileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B');
|
||||
|
||||
expect(notificationStub.notCalled).toEqual(true);
|
||||
});
|
||||
it('Moves list of files to target folder', function() {
|
||||
var request;
|
||||
FileList.move(['One.txt', 'Two.jpg'], '/somedir');
|
||||
|
||||
expect(fakeServer.requests.length).toEqual(2);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/move.php');
|
||||
expect(OC.parseQueryString(request.requestBody)).toEqual({dir: '/subdir', file: 'One.txt', target: '/somedir'});
|
||||
|
||||
request = fakeServer.requests[1];
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/move.php');
|
||||
expect(OC.parseQueryString(request.requestBody)).toEqual({dir: '/subdir', file: 'Two.jpg', target: '/somedir'});
|
||||
|
||||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'success',
|
||||
data: {
|
||||
name: 'One.txt',
|
||||
type: 'file'
|
||||
}
|
||||
}));
|
||||
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
|
||||
// folder size has increased
|
||||
expect(FileList.findFileEl('somedir').data('size')).toEqual(262);
|
||||
expect(FileList.findFileEl('somedir').find('.filesize').text()).toEqual('262 B');
|
||||
|
||||
fakeServer.requests[1].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'success',
|
||||
data: {
|
||||
name: 'Two.jpg',
|
||||
type: 'file'
|
||||
}
|
||||
}));
|
||||
|
||||
expect(FileList.findFileEl('Two.jpg').length).toEqual(0);
|
||||
|
||||
// folder size has increased
|
||||
expect(FileList.findFileEl('somedir').data('size')).toEqual(12311);
|
||||
expect(FileList.findFileEl('somedir').find('.filesize').text()).toEqual('12 kB');
|
||||
|
||||
expect(notificationStub.notCalled).toEqual(true);
|
||||
});
|
||||
it('Shows notification if a file could not be moved', function() {
|
||||
var request;
|
||||
FileList.move('One.txt', '/somedir');
|
||||
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/move.php');
|
||||
expect(OC.parseQueryString(request.requestBody)).toEqual({dir: '/subdir', file: 'One.txt', target: '/somedir'});
|
||||
|
||||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'error',
|
||||
data: {
|
||||
message: 'Error while moving file',
|
||||
}
|
||||
}));
|
||||
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(1);
|
||||
|
||||
expect(notificationStub.calledOnce).toEqual(true);
|
||||
expect(notificationStub.getCall(0).args[0]).toEqual('Error while moving file');
|
||||
});
|
||||
});
|
||||
describe('List rendering', function() {
|
||||
it('renders a list of files using add()', function() {
|
||||
var addSpy = sinon.spy(FileList, 'add');
|
||||
expect(FileList.files.length).toEqual(0);
|
||||
expect(FileList.files).toEqual([]);
|
||||
FileList.setFiles(testFiles);
|
||||
expect(addSpy.callCount).toEqual(4);
|
||||
expect($('#fileList tr:not(.summary)').length).toEqual(4);
|
||||
addSpy.restore();
|
||||
expect($('#fileList tr').length).toEqual(4);
|
||||
expect(FileList.files.length).toEqual(4);
|
||||
expect(FileList.files).toEqual(testFiles);
|
||||
});
|
||||
it('updates summary using the file sizes', function() {
|
||||
var $summary;
|
||||
FileList.setFiles(testFiles);
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(1);
|
||||
$summary = $('#filestable .summary');
|
||||
expect($summary.hasClass('hidden')).toEqual(false);
|
||||
expect($summary.find('.info').text()).toEqual('1 folder and 3 files');
|
||||
expect($summary.find('.filesize').text()).toEqual('69 kB');
|
||||
});
|
||||
|
|
@ -474,20 +656,20 @@ describe('FileList tests', function() {
|
|||
FileList.setFiles(testFiles);
|
||||
expect($('#filestable thead th').hasClass('hidden')).toEqual(false);
|
||||
expect($('#emptycontent').hasClass('hidden')).toEqual(true);
|
||||
expect(FileList.$fileList.find('.summary').length).toEqual(1);
|
||||
expect(FileList.$el.find('.summary').hasClass('hidden')).toEqual(false);
|
||||
});
|
||||
it('hides headers, summary and show empty content message after setting empty file list', function(){
|
||||
FileList.setFiles([]);
|
||||
expect($('#filestable thead th').hasClass('hidden')).toEqual(true);
|
||||
expect($('#emptycontent').hasClass('hidden')).toEqual(false);
|
||||
expect(FileList.$fileList.find('.summary').length).toEqual(0);
|
||||
expect(FileList.$el.find('.summary').hasClass('hidden')).toEqual(true);
|
||||
});
|
||||
it('hides headers, empty content message, and summary when list is empty and user has no creation permission', function(){
|
||||
$('#permissions').val(0);
|
||||
FileList.setFiles([]);
|
||||
expect($('#filestable thead th').hasClass('hidden')).toEqual(true);
|
||||
expect($('#emptycontent').hasClass('hidden')).toEqual(true);
|
||||
expect(FileList.$fileList.find('.summary').length).toEqual(0);
|
||||
expect(FileList.$el.find('.summary').hasClass('hidden')).toEqual(true);
|
||||
});
|
||||
it('calling findFileEl() can find existing file element', function() {
|
||||
FileList.setFiles(testFiles);
|
||||
|
|
@ -519,6 +701,110 @@ describe('FileList tests', function() {
|
|||
FileList.setFiles(testFiles);
|
||||
expect(handler.calledOnce).toEqual(true);
|
||||
});
|
||||
it('does not update summary when removing non-existing files', function() {
|
||||
// single file
|
||||
FileList.setFiles([testFiles[0]]);
|
||||
$summary = $('#filestable .summary');
|
||||
expect($summary.hasClass('hidden')).toEqual(false);
|
||||
expect($summary.find('.info').text()).toEqual('0 folders and 1 file');
|
||||
FileList.remove('unexist.txt');
|
||||
expect($summary.hasClass('hidden')).toEqual(false);
|
||||
expect($summary.find('.info').text()).toEqual('0 folders and 1 file');
|
||||
});
|
||||
});
|
||||
describe('Rendering next page on scroll', function() {
|
||||
beforeEach(function() {
|
||||
FileList.setFiles(generateFiles(0, 64));
|
||||
});
|
||||
it('renders only the first page', function() {
|
||||
expect(FileList.files.length).toEqual(65);
|
||||
expect($('#fileList tr').length).toEqual(20);
|
||||
});
|
||||
it('renders the second page when scrolling down (trigger nextPage)', function() {
|
||||
// TODO: can't simulate scrolling here, so calling nextPage directly
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(40);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(60);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(65);
|
||||
FileList._nextPage(true);
|
||||
// stays at 65
|
||||
expect($('#fileList tr').length).toEqual(65);
|
||||
});
|
||||
it('inserts into the DOM if insertion point is in the visible page ', function() {
|
||||
FileList.add({
|
||||
id: 2000,
|
||||
type: 'file',
|
||||
name: 'File with index 15b.txt'
|
||||
});
|
||||
expect($('#fileList tr').length).toEqual(21);
|
||||
expect(FileList.findFileEl('File with index 15b.txt').index()).toEqual(16);
|
||||
});
|
||||
it('does not inserts into the DOM if insertion point is not the visible page ', function() {
|
||||
FileList.add({
|
||||
id: 2000,
|
||||
type: 'file',
|
||||
name: 'File with index 28b.txt'
|
||||
});
|
||||
expect($('#fileList tr').length).toEqual(20);
|
||||
expect(FileList.findFileEl('File with index 28b.txt').length).toEqual(0);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(40);
|
||||
expect(FileList.findFileEl('File with index 28b.txt').index()).toEqual(29);
|
||||
});
|
||||
it('appends into the DOM when inserting a file after the last visible element', function() {
|
||||
FileList.add({
|
||||
id: 2000,
|
||||
type: 'file',
|
||||
name: 'File with index 19b.txt'
|
||||
});
|
||||
expect($('#fileList tr').length).toEqual(21);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(41);
|
||||
});
|
||||
it('appends into the DOM when inserting a file on the last page when visible', function() {
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(40);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(60);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(65);
|
||||
FileList._nextPage(true);
|
||||
FileList.add({
|
||||
id: 2000,
|
||||
type: 'file',
|
||||
name: 'File with index 88.txt'
|
||||
});
|
||||
expect($('#fileList tr').length).toEqual(66);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(66);
|
||||
});
|
||||
it('shows additional page when appending a page of files and scrolling down', function() {
|
||||
var newFiles = generateFiles(66, 81);
|
||||
for (var i = 0; i < newFiles.length; i++) {
|
||||
FileList.add(newFiles[i]);
|
||||
}
|
||||
expect($('#fileList tr').length).toEqual(20);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(40);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(60);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(80);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(81);
|
||||
FileList._nextPage(true);
|
||||
expect($('#fileList tr').length).toEqual(81);
|
||||
});
|
||||
it('automatically renders next page when there are not enough elements visible', function() {
|
||||
// delete the 15 first elements
|
||||
for (var i = 0; i < 15; i++) {
|
||||
FileList.remove(FileList.files[0].name);
|
||||
}
|
||||
// still makes sure that there are 20 elements visible, if any
|
||||
expect($('#fileList tr').length).toEqual(25);
|
||||
});
|
||||
});
|
||||
describe('file previews', function() {
|
||||
var previewLoadStub;
|
||||
|
|
@ -642,7 +928,7 @@ describe('FileList tests', function() {
|
|||
var query = url.substr(url.indexOf('?') + 1);
|
||||
expect(OC.parseQueryString(query)).toEqual({'dir': '/subdir'});
|
||||
fakeServer.respond();
|
||||
expect($('#fileList tr:not(.summary)').length).toEqual(4);
|
||||
expect($('#fileList tr').length).toEqual(4);
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(1);
|
||||
});
|
||||
it('switches dir and fetches file list when calling changeDirectory()', function() {
|
||||
|
|
@ -740,14 +1026,12 @@ describe('FileList tests', function() {
|
|||
}
|
||||
};
|
||||
// returns a list of tr that were dragged
|
||||
// FIXME: why are their attributes different than the
|
||||
// regular file trs ?
|
||||
ui.helper.find.returns([
|
||||
$('<tr data-filename="One.txt" data-dir="' + testDir + '"></tr>'),
|
||||
$('<tr data-filename="Two.jpg" data-dir="' + testDir + '"></tr>')
|
||||
$('<tr data-file="One.txt" data-dir="' + testDir + '"></tr>'),
|
||||
$('<tr data-file="Two.jpg" data-dir="' + testDir + '"></tr>')
|
||||
]);
|
||||
// simulate drop event
|
||||
FileList._onDropOnBreadCrumb.call($crumb, new $.Event('drop'), ui);
|
||||
FileList._onDropOnBreadCrumb(new $.Event('drop', {target: $crumb}), ui);
|
||||
|
||||
// will trigger two calls to move.php (first one was previous list.php)
|
||||
expect(fakeServer.requests.length).toEqual(3);
|
||||
|
|
@ -784,14 +1068,12 @@ describe('FileList tests', function() {
|
|||
}
|
||||
};
|
||||
// returns a list of tr that were dragged
|
||||
// FIXME: why are their attributes different than the
|
||||
// regular file trs ?
|
||||
ui.helper.find.returns([
|
||||
$('<tr data-filename="One.txt" data-dir="' + testDir + '"></tr>'),
|
||||
$('<tr data-filename="Two.jpg" data-dir="' + testDir + '"></tr>')
|
||||
$('<tr data-file="One.txt" data-dir="' + testDir + '"></tr>'),
|
||||
$('<tr data-file="Two.jpg" data-dir="' + testDir + '"></tr>')
|
||||
]);
|
||||
// simulate drop event
|
||||
FileList._onDropOnBreadCrumb.call($crumb, new $.Event('drop'), ui);
|
||||
FileList._onDropOnBreadCrumb(new $.Event('drop', {target: $crumb}), ui);
|
||||
|
||||
// no extra server request
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
|
|
@ -811,4 +1093,329 @@ describe('FileList tests', function() {
|
|||
expect(Files.getAjaxUrl('test', {a:1, b:'x y'})).toEqual(OC.webroot + '/index.php/apps/files/ajax/test.php?a=1&b=x%20y');
|
||||
});
|
||||
});
|
||||
describe('File selection', function() {
|
||||
beforeEach(function() {
|
||||
FileList.setFiles(testFiles);
|
||||
});
|
||||
it('Selects a file when clicking its checkbox', function() {
|
||||
var $tr = FileList.findFileEl('One.txt');
|
||||
expect($tr.find('input:checkbox').prop('checked')).toEqual(false);
|
||||
$tr.find('td.filename input:checkbox').click();
|
||||
|
||||
expect($tr.find('input:checkbox').prop('checked')).toEqual(true);
|
||||
});
|
||||
it('Selects/deselect a file when clicking on the name while holding Ctrl', function() {
|
||||
var $tr = FileList.findFileEl('One.txt');
|
||||
var $tr2 = FileList.findFileEl('Three.pdf');
|
||||
var e;
|
||||
expect($tr.find('input:checkbox').prop('checked')).toEqual(false);
|
||||
expect($tr2.find('input:checkbox').prop('checked')).toEqual(false);
|
||||
e = new $.Event('click');
|
||||
e.ctrlKey = true;
|
||||
$tr.find('td.filename .name').trigger(e);
|
||||
|
||||
expect($tr.find('input:checkbox').prop('checked')).toEqual(true);
|
||||
expect($tr2.find('input:checkbox').prop('checked')).toEqual(false);
|
||||
|
||||
// click on second entry, does not clear the selection
|
||||
e = new $.Event('click');
|
||||
e.ctrlKey = true;
|
||||
$tr2.find('td.filename .name').trigger(e);
|
||||
expect($tr.find('input:checkbox').prop('checked')).toEqual(true);
|
||||
expect($tr2.find('input:checkbox').prop('checked')).toEqual(true);
|
||||
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name')).toEqual(['One.txt', 'Three.pdf']);
|
||||
|
||||
// deselect now
|
||||
e = new $.Event('click');
|
||||
e.ctrlKey = true;
|
||||
$tr2.find('td.filename .name').trigger(e);
|
||||
expect($tr.find('input:checkbox').prop('checked')).toEqual(true);
|
||||
expect($tr2.find('input:checkbox').prop('checked')).toEqual(false);
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name')).toEqual(['One.txt']);
|
||||
});
|
||||
it('Selects a range when clicking on one file then Shift clicking on another one', function() {
|
||||
var $tr = FileList.findFileEl('One.txt');
|
||||
var $tr2 = FileList.findFileEl('Three.pdf');
|
||||
var e;
|
||||
$tr.find('td.filename input:checkbox').click();
|
||||
e = new $.Event('click');
|
||||
e.shiftKey = true;
|
||||
$tr2.find('td.filename .name').trigger(e);
|
||||
|
||||
expect($tr.find('input:checkbox').prop('checked')).toEqual(true);
|
||||
expect($tr2.find('input:checkbox').prop('checked')).toEqual(true);
|
||||
expect(FileList.findFileEl('Two.jpg').find('input:checkbox').prop('checked')).toEqual(true);
|
||||
var selection = _.pluck(FileList.getSelectedFiles(), 'name');
|
||||
expect(selection.length).toEqual(3);
|
||||
expect(selection).toContain('One.txt');
|
||||
expect(selection).toContain('Two.jpg');
|
||||
expect(selection).toContain('Three.pdf');
|
||||
});
|
||||
it('Selects a range when clicking on one file then Shift clicking on another one that is above the first one', function() {
|
||||
var $tr = FileList.findFileEl('One.txt');
|
||||
var $tr2 = FileList.findFileEl('Three.pdf');
|
||||
var e;
|
||||
$tr2.find('td.filename input:checkbox').click();
|
||||
e = new $.Event('click');
|
||||
e.shiftKey = true;
|
||||
$tr.find('td.filename .name').trigger(e);
|
||||
|
||||
expect($tr.find('input:checkbox').prop('checked')).toEqual(true);
|
||||
expect($tr2.find('input:checkbox').prop('checked')).toEqual(true);
|
||||
expect(FileList.findFileEl('Two.jpg').find('input:checkbox').prop('checked')).toEqual(true);
|
||||
var selection = _.pluck(FileList.getSelectedFiles(), 'name');
|
||||
expect(selection.length).toEqual(3);
|
||||
expect(selection).toContain('One.txt');
|
||||
expect(selection).toContain('Two.jpg');
|
||||
expect(selection).toContain('Three.pdf');
|
||||
});
|
||||
it('Selecting all files will automatically check "select all" checkbox', function() {
|
||||
expect($('#select_all').prop('checked')).toEqual(false);
|
||||
$('#fileList tr td.filename input:checkbox').click();
|
||||
expect($('#select_all').prop('checked')).toEqual(true);
|
||||
});
|
||||
it('Selecting all files on the first visible page will not automatically check "select all" checkbox', function() {
|
||||
FileList.setFiles(generateFiles(0, 41));
|
||||
expect($('#select_all').prop('checked')).toEqual(false);
|
||||
$('#fileList tr td.filename input:checkbox').click();
|
||||
expect($('#select_all').prop('checked')).toEqual(false);
|
||||
});
|
||||
it('Clicking "select all" will select/deselect all files', function() {
|
||||
FileList.setFiles(generateFiles(0, 41));
|
||||
$('#select_all').click();
|
||||
expect($('#select_all').prop('checked')).toEqual(true);
|
||||
$('#fileList tr input:checkbox').each(function() {
|
||||
expect($(this).prop('checked')).toEqual(true);
|
||||
});
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(42);
|
||||
|
||||
$('#select_all').click();
|
||||
expect($('#select_all').prop('checked')).toEqual(false);
|
||||
|
||||
$('#fileList tr input:checkbox').each(function() {
|
||||
expect($(this).prop('checked')).toEqual(false);
|
||||
});
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(0);
|
||||
});
|
||||
it('Clicking "select all" then deselecting a file will uncheck "select all"', function() {
|
||||
$('#select_all').click();
|
||||
expect($('#select_all').prop('checked')).toEqual(true);
|
||||
|
||||
var $tr = FileList.findFileEl('One.txt');
|
||||
$tr.find('input:checkbox').click();
|
||||
|
||||
expect($('#select_all').prop('checked')).toEqual(false);
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(3);
|
||||
});
|
||||
it('Updates the selection summary when doing a few manipulations with "Select all"', function() {
|
||||
$('#select_all').click();
|
||||
expect($('#select_all').prop('checked')).toEqual(true);
|
||||
|
||||
var $tr = FileList.findFileEl('One.txt');
|
||||
// unselect one
|
||||
$tr.find('input:checkbox').click();
|
||||
|
||||
expect($('#select_all').prop('checked')).toEqual(false);
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(3);
|
||||
|
||||
// select all
|
||||
$('#select_all').click();
|
||||
expect($('#select_all').prop('checked')).toEqual(true);
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(4);
|
||||
|
||||
// unselect one
|
||||
$tr.find('input:checkbox').click();
|
||||
expect($('#select_all').prop('checked')).toEqual(false);
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(3);
|
||||
|
||||
// re-select it
|
||||
$tr.find('input:checkbox').click();
|
||||
expect($('#select_all').prop('checked')).toEqual(true);
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(4);
|
||||
});
|
||||
it('Auto-selects files on next page when "select all" is checked', function() {
|
||||
FileList.setFiles(generateFiles(0, 41));
|
||||
$('#select_all').click();
|
||||
|
||||
expect(FileList.$fileList.find('tr input:checkbox:checked').length).toEqual(20);
|
||||
FileList._nextPage(true);
|
||||
expect(FileList.$fileList.find('tr input:checkbox:checked').length).toEqual(40);
|
||||
FileList._nextPage(true);
|
||||
expect(FileList.$fileList.find('tr input:checkbox:checked').length).toEqual(42);
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name').length).toEqual(42);
|
||||
});
|
||||
it('Selecting files updates selection summary', function() {
|
||||
var $summary = $('#headerName span.name');
|
||||
expect($summary.text()).toEqual('Name');
|
||||
FileList.findFileEl('One.txt').find('input:checkbox').click();
|
||||
FileList.findFileEl('Three.pdf').find('input:checkbox').click();
|
||||
FileList.findFileEl('somedir').find('input:checkbox').click();
|
||||
expect($summary.text()).toEqual('1 folder & 2 files');
|
||||
});
|
||||
it('Unselecting files hides selection summary', function() {
|
||||
var $summary = $('#headerName span.name');
|
||||
FileList.findFileEl('One.txt').find('input:checkbox').click().click();
|
||||
expect($summary.text()).toEqual('Name');
|
||||
});
|
||||
it('Select/deselect files shows/hides file actions', function() {
|
||||
var $actions = $('#headerName .selectedActions');
|
||||
var $checkbox = FileList.findFileEl('One.txt').find('input:checkbox');
|
||||
expect($actions.hasClass('hidden')).toEqual(true);
|
||||
$checkbox.click();
|
||||
expect($actions.hasClass('hidden')).toEqual(false);
|
||||
$checkbox.click();
|
||||
expect($actions.hasClass('hidden')).toEqual(true);
|
||||
});
|
||||
it('Selection is cleared when switching dirs', function() {
|
||||
$('#select_all').click();
|
||||
var data = {
|
||||
status: 'success',
|
||||
data: {
|
||||
files: testFiles,
|
||||
permissions: 31
|
||||
}
|
||||
};
|
||||
fakeServer.respondWith(/\/index\.php\/apps\/files\/ajax\/list.php/, [
|
||||
200, {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
JSON.stringify(data)
|
||||
]);
|
||||
FileList.changeDirectory('/');
|
||||
fakeServer.respond();
|
||||
expect($('#select_all').prop('checked')).toEqual(false);
|
||||
expect(_.pluck(FileList.getSelectedFiles(), 'name')).toEqual([]);
|
||||
});
|
||||
it('getSelectedFiles returns the selected files even when they are on the next page', function() {
|
||||
var selectedFiles;
|
||||
FileList.setFiles(generateFiles(0, 41));
|
||||
$('#select_all').click();
|
||||
// unselect one to not have the "allFiles" case
|
||||
FileList.$fileList.find('tr input:checkbox:first').click();
|
||||
|
||||
// only 20 files visible, must still return all the selected ones
|
||||
selectedFiles = _.pluck(FileList.getSelectedFiles(), 'name');
|
||||
|
||||
expect(selectedFiles.length).toEqual(41);
|
||||
});
|
||||
describe('Actions', function() {
|
||||
beforeEach(function() {
|
||||
FileList.findFileEl('One.txt').find('input:checkbox').click();
|
||||
FileList.findFileEl('Three.pdf').find('input:checkbox').click();
|
||||
FileList.findFileEl('somedir').find('input:checkbox').click();
|
||||
});
|
||||
it('getSelectedFiles returns the selected file data', function() {
|
||||
var files = FileList.getSelectedFiles();
|
||||
expect(files.length).toEqual(3);
|
||||
expect(files[0]).toEqual({
|
||||
id: 1,
|
||||
name: 'One.txt',
|
||||
mimetype: 'text/plain',
|
||||
type: 'file',
|
||||
size: 12,
|
||||
etag: 'abc'
|
||||
});
|
||||
expect(files[1]).toEqual({
|
||||
id: 3,
|
||||
type: 'file',
|
||||
name: 'Three.pdf',
|
||||
mimetype: 'application/pdf',
|
||||
size: 58009,
|
||||
etag: '123'
|
||||
});
|
||||
expect(files[2]).toEqual({
|
||||
id: 4,
|
||||
type: 'dir',
|
||||
name: 'somedir',
|
||||
mimetype: 'httpd/unix-directory',
|
||||
size: 250,
|
||||
etag: '456'
|
||||
});
|
||||
});
|
||||
it('Removing a file removes it from the selection', function() {
|
||||
FileList.remove('Three.pdf');
|
||||
var files = FileList.getSelectedFiles();
|
||||
expect(files.length).toEqual(2);
|
||||
expect(files[0]).toEqual({
|
||||
id: 1,
|
||||
name: 'One.txt',
|
||||
mimetype: 'text/plain',
|
||||
type: 'file',
|
||||
size: 12,
|
||||
etag: 'abc'
|
||||
});
|
||||
expect(files[1]).toEqual({
|
||||
id: 4,
|
||||
type: 'dir',
|
||||
name: 'somedir',
|
||||
mimetype: 'httpd/unix-directory',
|
||||
size: 250,
|
||||
etag: '456'
|
||||
});
|
||||
});
|
||||
describe('Download', function() {
|
||||
it('Opens download URL when clicking "Download"', function() {
|
||||
var redirectStub = sinon.stub(OC, 'redirect');
|
||||
$('.selectedActions .download').click();
|
||||
expect(redirectStub.calledOnce).toEqual(true);
|
||||
expect(redirectStub.getCall(0).args[0]).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22One.txt%22%2C%22Three.pdf%22%2C%22somedir%22%5D');
|
||||
redirectStub.restore();
|
||||
});
|
||||
it('Downloads root folder when all selected in root folder', function() {
|
||||
$('#dir').val('/');
|
||||
$('#select_all').click();
|
||||
var redirectStub = sinon.stub(OC, 'redirect');
|
||||
$('.selectedActions .download').click();
|
||||
expect(redirectStub.calledOnce).toEqual(true);
|
||||
expect(redirectStub.getCall(0).args[0]).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=');
|
||||
redirectStub.restore();
|
||||
});
|
||||
it('Downloads parent folder when all selected in subfolder', function() {
|
||||
$('#select_all').click();
|
||||
var redirectStub = sinon.stub(OC, 'redirect');
|
||||
$('.selectedActions .download').click();
|
||||
expect(redirectStub.calledOnce).toEqual(true);
|
||||
expect(redirectStub.getCall(0).args[0]).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=subdir');
|
||||
redirectStub.restore();
|
||||
});
|
||||
});
|
||||
describe('Delete', function() {
|
||||
it('Deletes selected files when "Delete" clicked', function() {
|
||||
var request;
|
||||
$('.selectedActions .delete-selected').click();
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/delete.php');
|
||||
expect(OC.parseQueryString(request.requestBody))
|
||||
.toEqual({'dir': '/subdir', files: '["One.txt","Three.pdf","somedir"]'});
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify({status: 'success'})
|
||||
);
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
expect(FileList.findFileEl('Three.pdf').length).toEqual(0);
|
||||
expect(FileList.findFileEl('somedir').length).toEqual(0);
|
||||
expect(FileList.findFileEl('Two.jpg').length).toEqual(1);
|
||||
});
|
||||
it('Deletes all files when all selected when "Delete" clicked', function() {
|
||||
var request;
|
||||
$('#select_all').click();
|
||||
$('.selectedActions .delete-selected').click();
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/delete.php');
|
||||
expect(OC.parseQueryString(request.requestBody))
|
||||
.toEqual({'dir': '/subdir', allfiles: 'true'});
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify({status: 'success'})
|
||||
);
|
||||
expect(FileList.isEmpty).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* global Files */
|
||||
/* global OC, Files */
|
||||
describe('Files tests', function() {
|
||||
describe('File name validation', function() {
|
||||
it('Validates correct file names', function() {
|
||||
|
|
@ -82,4 +82,30 @@ describe('Files tests', function() {
|
|||
}
|
||||
});
|
||||
});
|
||||
describe('getDownloadUrl', function() {
|
||||
var curDirStub;
|
||||
beforeEach(function() {
|
||||
curDirStub = sinon.stub(FileList, 'getCurrentDirectory');
|
||||
});
|
||||
afterEach(function() {
|
||||
curDirStub.restore();
|
||||
});
|
||||
it('returns the ajax download URL when only filename specified', function() {
|
||||
curDirStub.returns('/subdir');
|
||||
var url = Files.getDownloadUrl('test file.txt');
|
||||
expect(url).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=test%20file.txt');
|
||||
});
|
||||
it('returns the ajax download URL when filename and dir specified', function() {
|
||||
var url = Files.getDownloadUrl('test file.txt', '/subdir');
|
||||
expect(url).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=test%20file.txt');
|
||||
});
|
||||
it('returns the ajax download URL when filename and root dir specific', function() {
|
||||
var url = Files.getDownloadUrl('test file.txt', '/');
|
||||
expect(url).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=test%20file.txt');
|
||||
});
|
||||
it('returns the ajax download URL when multiple files specified', function() {
|
||||
var url = Files.getDownloadUrl(['test file.txt', 'abc.txt'], '/subdir');
|
||||
expect(url).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22test%20file.txt%22%2C%22abc.txt%22%5D');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
87
apps/files/tests/js/filesummarySpec.js
Normal file
87
apps/files/tests/js/filesummarySpec.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Vincent Petry
|
||||
* @copyright 2014 Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global FileSummary */
|
||||
describe('FileSummary tests', function() {
|
||||
var $container;
|
||||
|
||||
beforeEach(function() {
|
||||
$container = $('<table><tr></tr></table>').find('tr');
|
||||
});
|
||||
afterEach(function() {
|
||||
$container = null;
|
||||
});
|
||||
|
||||
it('renders summary as text', function() {
|
||||
var s = new FileSummary($container);
|
||||
s.setSummary({
|
||||
totalDirs: 5,
|
||||
totalFiles: 2,
|
||||
totalSize: 256000
|
||||
});
|
||||
expect($container.hasClass('hidden')).toEqual(false);
|
||||
expect($container.find('.info').text()).toEqual('5 folders and 2 files');
|
||||
expect($container.find('.filesize').text()).toEqual('250 kB');
|
||||
});
|
||||
it('hides summary when no files or folders', function() {
|
||||
var s = new FileSummary($container);
|
||||
s.setSummary({
|
||||
totalDirs: 0,
|
||||
totalFiles: 0,
|
||||
totalSize: 0
|
||||
});
|
||||
expect($container.hasClass('hidden')).toEqual(true);
|
||||
});
|
||||
it('increases summary when adding files', function() {
|
||||
var s = new FileSummary($container);
|
||||
s.setSummary({
|
||||
totalDirs: 5,
|
||||
totalFiles: 2,
|
||||
totalSize: 256000
|
||||
});
|
||||
s.add({type: 'file', size: 256000});
|
||||
s.add({type: 'dir', size: 100});
|
||||
s.update();
|
||||
expect($container.hasClass('hidden')).toEqual(false);
|
||||
expect($container.find('.info').text()).toEqual('6 folders and 3 files');
|
||||
expect($container.find('.filesize').text()).toEqual('500 kB');
|
||||
expect(s.summary.totalDirs).toEqual(6);
|
||||
expect(s.summary.totalFiles).toEqual(3);
|
||||
expect(s.summary.totalSize).toEqual(512100);
|
||||
});
|
||||
it('decreases summary when removing files', function() {
|
||||
var s = new FileSummary($container);
|
||||
s.setSummary({
|
||||
totalDirs: 5,
|
||||
totalFiles: 2,
|
||||
totalSize: 256000
|
||||
});
|
||||
s.remove({type: 'file', size: 128000});
|
||||
s.remove({type: 'dir', size: 100});
|
||||
s.update();
|
||||
expect($container.hasClass('hidden')).toEqual(false);
|
||||
expect($container.find('.info').text()).toEqual('4 folders and 1 file');
|
||||
expect($container.find('.filesize').text()).toEqual('125 kB');
|
||||
expect(s.summary.totalDirs).toEqual(4);
|
||||
expect(s.summary.totalFiles).toEqual(1);
|
||||
expect(s.summary.totalSize).toEqual(127900);
|
||||
});
|
||||
});
|
||||
|
|
@ -138,6 +138,7 @@ if (isset($path)) {
|
|||
|
||||
OCP\Util::addStyle('files', 'files');
|
||||
OCP\Util::addStyle('files', 'upload');
|
||||
OCP\Util::addScript('files', 'filesummary');
|
||||
OCP\Util::addScript('files', 'breadcrumb');
|
||||
OCP\Util::addScript('files', 'files');
|
||||
OCP\Util::addScript('files', 'filelist');
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ $tmpl = new OCP\Template('files_trashbin', 'index', 'user');
|
|||
|
||||
OCP\Util::addStyle('files', 'files');
|
||||
OCP\Util::addStyle('files_trashbin', 'trash');
|
||||
OCP\Util::addScript('files', 'filesummary');
|
||||
OCP\Util::addScript('files', 'breadcrumb');
|
||||
OCP\Util::addScript('files', 'filelist');
|
||||
// filelist overrides
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@
|
|||
}
|
||||
};
|
||||
|
||||
var oldAdd = FileList.add;
|
||||
FileList.add = function(fileData, options) {
|
||||
var oldRenderRow = FileList._renderRow;
|
||||
FileList._renderRow = function(fileData, options) {
|
||||
options = options || {};
|
||||
var dir = FileList.getCurrentDirectory();
|
||||
var dirListing = dir !== '' && dir !== '/';
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
fileData.displayName = fileData.name;
|
||||
fileData.name = fileData.name + '.d' + Math.floor(fileData.mtime / 1000);
|
||||
}
|
||||
return oldAdd.call(this, fileData, options);
|
||||
return oldRenderRow.call(this, fileData, options);
|
||||
};
|
||||
|
||||
FileList.linkTo = function(dir){
|
||||
|
|
@ -75,4 +75,130 @@
|
|||
$('#emptycontent').toggleClass('hidden', exists);
|
||||
$('#filestable th').toggleClass('hidden', !exists);
|
||||
};
|
||||
|
||||
var oldInit = FileList.initialize;
|
||||
FileList.initialize = function() {
|
||||
var result = oldInit.apply(this, arguments);
|
||||
$('.undelete').click('click', FileList._onClickRestoreSelected);
|
||||
return result;
|
||||
};
|
||||
|
||||
FileList._removeCallback = function(result) {
|
||||
if (result.status !== 'success') {
|
||||
OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error'));
|
||||
}
|
||||
|
||||
var files = result.data.success;
|
||||
var $el;
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
$el = FileList.remove(OC.basename(files[i].filename), {updateSummary: false});
|
||||
FileList.fileSummary.remove({type: $el.attr('data-type'), size: $el.attr('data-size')});
|
||||
}
|
||||
FileList.fileSummary.update();
|
||||
FileList.updateEmptyContent();
|
||||
enableActions();
|
||||
}
|
||||
|
||||
FileList._onClickRestoreSelected = function(event) {
|
||||
event.preventDefault();
|
||||
var allFiles = $('#select_all').is(':checked');
|
||||
var files = [];
|
||||
var params = {};
|
||||
disableActions();
|
||||
if (allFiles) {
|
||||
FileList.showMask();
|
||||
params = {
|
||||
allfiles: true,
|
||||
dir: FileList.getCurrentDirectory()
|
||||
};
|
||||
}
|
||||
else {
|
||||
files = _.pluck(FileList.getSelectedFiles(), 'name');
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete");
|
||||
deleteAction.removeClass('delete-icon').addClass('progress-icon');
|
||||
}
|
||||
params = {
|
||||
files: JSON.stringify(files),
|
||||
dir: FileList.getCurrentDirectory()
|
||||
};
|
||||
}
|
||||
|
||||
$.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'),
|
||||
params,
|
||||
function(result) {
|
||||
if (allFiles) {
|
||||
if (result.status !== 'success') {
|
||||
OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error'));
|
||||
}
|
||||
FileList.hideMask();
|
||||
// simply remove all files
|
||||
FileList.setFiles([]);
|
||||
enableActions();
|
||||
}
|
||||
else {
|
||||
FileList._removeCallback(result);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
FileList._onClickDeleteSelected = function(event) {
|
||||
event.preventDefault();
|
||||
var allFiles = $('#select_all').is(':checked');
|
||||
var files = [];
|
||||
var params = {};
|
||||
if (allFiles) {
|
||||
params = {
|
||||
allfiles: true,
|
||||
dir: FileList.getCurrentDirectory()
|
||||
};
|
||||
}
|
||||
else {
|
||||
files = _.pluck(FileList.getSelectedFiles(), 'name');
|
||||
params = {
|
||||
files: JSON.stringify(files),
|
||||
dir: FileList.getCurrentDirectory()
|
||||
};
|
||||
}
|
||||
|
||||
disableActions();
|
||||
if (allFiles) {
|
||||
FileList.showMask();
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete");
|
||||
deleteAction.removeClass('delete-icon').addClass('progress-icon');
|
||||
}
|
||||
}
|
||||
|
||||
$.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'),
|
||||
params,
|
||||
function(result) {
|
||||
if (allFiles) {
|
||||
if (result.status !== 'success') {
|
||||
OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error'));
|
||||
}
|
||||
FileList.hideMask();
|
||||
// simply remove all files
|
||||
FileList.setFiles([]);
|
||||
enableActions();
|
||||
}
|
||||
else {
|
||||
FileList._removeCallback(result);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
var oldClickFile = FileList._onClickFile;
|
||||
FileList._onClickFile = function(event) {
|
||||
var mime = $(this).parent().parent().data('mime');
|
||||
if (mime !== 'httpd/unix-directory') {
|
||||
event.preventDefault();
|
||||
}
|
||||
return oldClickFile.apply(this, arguments);
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -28,20 +28,6 @@ $(document).ready(function() {
|
|||
return name;
|
||||
}
|
||||
|
||||
function removeCallback(result) {
|
||||
if (result.status !== 'success') {
|
||||
OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error'));
|
||||
}
|
||||
|
||||
var files = result.data.success;
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
FileList.remove(OC.basename(files[i].filename), {updateSummary: false});
|
||||
}
|
||||
FileList.updateFileSummary();
|
||||
FileList.updateEmptyContent();
|
||||
enableActions();
|
||||
}
|
||||
|
||||
Files.updateStorageStatistics = function() {
|
||||
// no op because the trashbin doesn't have
|
||||
// storage info like free space / used space
|
||||
|
|
@ -57,7 +43,7 @@ $(document).ready(function() {
|
|||
files: JSON.stringify([filename]),
|
||||
dir: FileList.getCurrentDirectory()
|
||||
},
|
||||
removeCallback
|
||||
FileList._removeCallback
|
||||
);
|
||||
}, t('files_trashbin', 'Restore'));
|
||||
};
|
||||
|
|
@ -74,153 +60,10 @@ $(document).ready(function() {
|
|||
files: JSON.stringify([filename]),
|
||||
dir: FileList.getCurrentDirectory()
|
||||
},
|
||||
removeCallback
|
||||
FileList._removeCallback
|
||||
);
|
||||
});
|
||||
|
||||
// Sets the select_all checkbox behaviour :
|
||||
$('#select_all').click(function() {
|
||||
if ($(this).attr('checked')) {
|
||||
// Check all
|
||||
$('td.filename input:checkbox').attr('checked', true);
|
||||
$('td.filename input:checkbox').parent().parent().addClass('selected');
|
||||
} else {
|
||||
// Uncheck all
|
||||
$('td.filename input:checkbox').attr('checked', false);
|
||||
$('td.filename input:checkbox').parent().parent().removeClass('selected');
|
||||
}
|
||||
procesSelection();
|
||||
});
|
||||
$('.undelete').click('click', function(event) {
|
||||
event.preventDefault();
|
||||
var allFiles = $('#select_all').is(':checked');
|
||||
var files = [];
|
||||
var params = {};
|
||||
disableActions();
|
||||
if (allFiles) {
|
||||
FileList.showMask();
|
||||
params = {
|
||||
allfiles: true,
|
||||
dir: FileList.getCurrentDirectory()
|
||||
};
|
||||
}
|
||||
else {
|
||||
files = Files.getSelectedFiles('name');
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete");
|
||||
deleteAction.removeClass('delete-icon').addClass('progress-icon');
|
||||
}
|
||||
params = {
|
||||
files: JSON.stringify(files),
|
||||
dir: FileList.getCurrentDirectory()
|
||||
};
|
||||
}
|
||||
|
||||
$.post(OC.filePath('files_trashbin', 'ajax', 'undelete.php'),
|
||||
params,
|
||||
function(result) {
|
||||
if (allFiles) {
|
||||
if (result.status !== 'success') {
|
||||
OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error'));
|
||||
}
|
||||
FileList.hideMask();
|
||||
// simply remove all files
|
||||
FileList.update('');
|
||||
enableActions();
|
||||
}
|
||||
else {
|
||||
removeCallback(result);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('.delete').click('click', function(event) {
|
||||
event.preventDefault();
|
||||
var allFiles = $('#select_all').is(':checked');
|
||||
var files = [];
|
||||
var params = {};
|
||||
if (allFiles) {
|
||||
params = {
|
||||
allfiles: true,
|
||||
dir: FileList.getCurrentDirectory()
|
||||
};
|
||||
}
|
||||
else {
|
||||
files = Files.getSelectedFiles('name');
|
||||
params = {
|
||||
files: JSON.stringify(files),
|
||||
dir: FileList.getCurrentDirectory()
|
||||
};
|
||||
}
|
||||
|
||||
disableActions();
|
||||
if (allFiles) {
|
||||
FileList.showMask();
|
||||
}
|
||||
else {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var deleteAction = FileList.findFileEl(files[i]).children("td.date").children(".action.delete");
|
||||
deleteAction.removeClass('delete-icon').addClass('progress-icon');
|
||||
}
|
||||
}
|
||||
|
||||
$.post(OC.filePath('files_trashbin', 'ajax', 'delete.php'),
|
||||
params,
|
||||
function(result) {
|
||||
if (allFiles) {
|
||||
if (result.status !== 'success') {
|
||||
OC.dialogs.alert(result.data.message, t('files_trashbin', 'Error'));
|
||||
}
|
||||
FileList.hideMask();
|
||||
// simply remove all files
|
||||
FileList.setFiles([]);
|
||||
enableActions();
|
||||
}
|
||||
else {
|
||||
removeCallback(result);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
$('#fileList').on('click', 'td.filename input', function() {
|
||||
var checkbox = $(this).parent().children('input:checkbox');
|
||||
$(checkbox).parent().parent().toggleClass('selected');
|
||||
if ($(checkbox).is(':checked')) {
|
||||
var selectedCount = $('td.filename input:checkbox:checked').length;
|
||||
if (selectedCount === $('td.filename input:checkbox').length) {
|
||||
$('#select_all').prop('checked', true);
|
||||
}
|
||||
} else {
|
||||
$('#select_all').prop('checked',false);
|
||||
}
|
||||
procesSelection();
|
||||
});
|
||||
|
||||
$('#fileList').on('click', 'td.filename a', function(event) {
|
||||
var mime = $(this).parent().parent().data('mime');
|
||||
if (mime !== 'httpd/unix-directory') {
|
||||
event.preventDefault();
|
||||
}
|
||||
var filename = $(this).parent().parent().attr('data-file');
|
||||
var tr = FileList.findFileEl(filename);
|
||||
var renaming = tr.data('renaming');
|
||||
if(!renaming){
|
||||
if(mime.substr(0, 5) === 'text/'){ //no texteditor for now
|
||||
return;
|
||||
}
|
||||
var type = $(this).parent().parent().data('type');
|
||||
var permissions = $(this).parent().parent().data('permissions');
|
||||
var action = FileActions.getDefault(mime, type, permissions);
|
||||
if(action){
|
||||
event.preventDefault();
|
||||
action(filename);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Override crumb URL maker (hacky!)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
<th id="headerDate">
|
||||
<span id="modified"><?php p($l->t( 'Deleted' )); ?></span>
|
||||
<span class="selectedActions">
|
||||
<a href="" class="delete">
|
||||
<a href="" class="delete-selected">
|
||||
<?php p($l->t('Delete'))?>
|
||||
<img class="svg" alt="<?php p($l->t('Delete'))?>"
|
||||
src="<?php print_unescaped(OCP\image_path("core", "actions/delete.svg")); ?>" />
|
||||
|
|
@ -40,4 +40,6 @@
|
|||
</thead>
|
||||
<tbody id="fileList">
|
||||
</tbody>
|
||||
<tfoot>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -243,7 +243,6 @@ button.loading {
|
|||
padding-right: 30px;
|
||||
}
|
||||
|
||||
|
||||
/* general styles for the content area */
|
||||
.section {
|
||||
display: block;
|
||||
|
|
@ -264,3 +263,14 @@ button.loading {
|
|||
vertical-align: -2px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
.appear {
|
||||
opacity: 1;
|
||||
transition: opacity 500ms ease 0s;
|
||||
-moz-transition: opacity 500ms ease 0s;
|
||||
-ms-transition: opacity 500ms ease 0s;
|
||||
-o-transition: opacity 500ms ease 0s;
|
||||
-webkit-transition: opacity 500ms ease 0s;
|
||||
}
|
||||
.appear.transparent {
|
||||
opacity: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1250,9 +1250,12 @@ function relative_modified_date(timestamp) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @todo Write documentation
|
||||
* Utility functions
|
||||
*/
|
||||
OC.Util = {
|
||||
// TODO: remove original functions from global namespace
|
||||
humanFileSize: humanFileSize,
|
||||
formatDate: formatDate,
|
||||
/**
|
||||
* Returns whether the browser supports SVG
|
||||
* @return {boolean} true if the browser supports SVG, false otherwise
|
||||
|
|
|
|||
|
|
@ -474,5 +474,22 @@ describe('Core base tests', function() {
|
|||
);
|
||||
});
|
||||
});
|
||||
describe('Util', function() {
|
||||
describe('humanFileSize', function() {
|
||||
it('renders file sizes with the correct unit', function() {
|
||||
var data = [
|
||||
[0, '0 B'],
|
||||
[125, '125 B'],
|
||||
[128000, '125 kB'],
|
||||
[128000000, '122.1 MB'],
|
||||
[128000000000, '119.2 GB'],
|
||||
[128000000000000, '116.4 TB']
|
||||
];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
expect(OC.Util.humanFileSize(data[i][0])).toEqual(data[i][1]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue