Merge pull request #6968 from owncloud/files-ajaxload
Ajaxify files list for files + trashbin + public page
This commit is contained in:
commit
bf7624fb25
|
@ -7,37 +7,21 @@ OCP\JSON::checkLoggedIn();
|
|||
$dir = isset( $_GET['dir'] ) ? $_GET['dir'] : '';
|
||||
$dir = \OC\Files\Filesystem::normalizePath($dir);
|
||||
$dirInfo = \OC\Files\Filesystem::getFileInfo($dir);
|
||||
if (!$dirInfo->getType() === 'dir') {
|
||||
if (!$dirInfo || !$dirInfo->getType() === 'dir') {
|
||||
header("HTTP/1.0 404 Not Found");
|
||||
exit();
|
||||
}
|
||||
|
||||
$doBreadcrumb = isset($_GET['breadcrumb']);
|
||||
$data = array();
|
||||
$baseUrl = OCP\Util::linkTo('files', 'index.php') . '?dir=';
|
||||
|
||||
$permissions = $dirInfo->getPermissions();
|
||||
|
||||
// Make breadcrumb
|
||||
if($doBreadcrumb) {
|
||||
$breadcrumb = \OCA\Files\Helper::makeBreadcrumb($dir);
|
||||
|
||||
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
|
||||
$breadcrumbNav->assign('breadcrumb', $breadcrumb, false);
|
||||
$breadcrumbNav->assign('baseURL', $baseUrl);
|
||||
|
||||
$data['breadcrumb'] = $breadcrumbNav->fetchPage();
|
||||
}
|
||||
|
||||
// make filelist
|
||||
$files = \OCA\Files\Helper::getFiles($dir);
|
||||
|
||||
$list = new OCP\Template("files", "part.list", "");
|
||||
$list->assign('files', $files, false);
|
||||
$list->assign('baseURL', $baseUrl, false);
|
||||
$list->assign('downloadURL', OCP\Util::linkToRoute('download', array('file' => '/')));
|
||||
$list->assign('isPublic', false);
|
||||
$data['files'] = $list->fetchPage();
|
||||
$data['directory'] = $dir;
|
||||
$data['files'] = \OCA\Files\Helper::formatFileInfos($files);
|
||||
$data['permissions'] = $permissions;
|
||||
|
||||
OCP\JSON::success(array('data' => $data));
|
||||
|
|
|
@ -112,9 +112,8 @@ if($source) {
|
|||
}
|
||||
if($result) {
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($target);
|
||||
$mime=$meta['mimetype'];
|
||||
$id = $meta['fileid'];
|
||||
$eventSource->send('success', array('mime' => $mime, 'size' => \OC\Files\Filesystem::filesize($target), 'id' => $id, 'etag' => $meta['etag']));
|
||||
$data = \OCA\Files\Helper::formatFileInfo($meta);
|
||||
$eventSource->send('success', $data);
|
||||
} else {
|
||||
$eventSource->send('error', array('message' => $l10n->t('Error while downloading %s to %s', array($source, $target))));
|
||||
}
|
||||
|
@ -139,16 +138,7 @@ if($source) {
|
|||
|
||||
if($success) {
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($target);
|
||||
$id = $meta['fileid'];
|
||||
$mime = $meta['mimetype'];
|
||||
$size = $meta['size'];
|
||||
OCP\JSON::success(array('data' => array(
|
||||
'id' => $id,
|
||||
'mime' => $mime,
|
||||
'size' => $size,
|
||||
'content' => $content,
|
||||
'etag' => $meta['etag'],
|
||||
)));
|
||||
OCP\JSON::success(array('data' => \OCA\Files\Helper::formatFileInfo($meta)));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,8 +58,8 @@ if(\OC\Files\Filesystem::mkdir($target)) {
|
|||
$path = '/'.$foldername;
|
||||
}
|
||||
$meta = \OC\Files\Filesystem::getFileInfo($path);
|
||||
$id = $meta['fileid'];
|
||||
OCP\JSON::success(array('data' => array('id' => $id)));
|
||||
$meta['type'] = 'dir'; // missing ?!
|
||||
OCP\JSON::success(array('data' => \OCA\Files\Helper::formatFileInfo($meta)));
|
||||
exit();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
<?php
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
\OC::$session->close();
|
||||
|
||||
// Load the files
|
||||
$dir = isset($_GET['dir']) ? $_GET['dir'] : '';
|
||||
$mimetypes = isset($_GET['mimetypes']) ? json_decode($_GET['mimetypes'], true) : '';
|
||||
|
||||
// Clean up duplicates from array and deal with non-array requests
|
||||
if (is_array($mimetypes)) {
|
||||
$mimetypes = array_unique($mimetypes);
|
||||
} elseif (is_null($mimetypes)) {
|
||||
$mimetypes = array($_GET['mimetypes']);
|
||||
}
|
||||
|
||||
// make filelist
|
||||
$files = array();
|
||||
/**
|
||||
* @var \OCP\Files\FileInfo[] $files
|
||||
*/
|
||||
// If a type other than directory is requested first load them.
|
||||
if ($mimetypes && !in_array('httpd/unix-directory', $mimetypes)) {
|
||||
$files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir, 'httpd/unix-directory'));
|
||||
}
|
||||
|
||||
if (is_array($mimetypes) && count($mimetypes)) {
|
||||
foreach ($mimetypes as $mimetype) {
|
||||
$files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir, $mimetype));
|
||||
}
|
||||
} else {
|
||||
$files = array_merge($files, \OC\Files\Filesystem::getDirectoryContent($dir));
|
||||
}
|
||||
// Sort by name
|
||||
usort($files, array('\OCA\Files\Helper', 'fileCmp'));
|
||||
|
||||
$result = array();
|
||||
foreach ($files as $file) {
|
||||
$fileData = array();
|
||||
$fileData['directory'] = $dir;
|
||||
$fileData['name'] = $file->getName();
|
||||
$fileData['type'] = $file->getType();
|
||||
$fileData['path'] = $file['path'];
|
||||
$fileData['id'] = $file->getId();
|
||||
$fileData['size'] = $file->getSize();
|
||||
$fileData['mtime'] = $file->getMtime();
|
||||
$fileData['mimetype'] = $file->getMimetype();
|
||||
$fileData['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($file->getMimetype());
|
||||
$fileData["date"] = OCP\Util::formatDate($file->getMtime());
|
||||
$fileData['mimetype_icon'] = \OCA\Files\Helper::determineIcon($file);
|
||||
$result[] = $fileData;
|
||||
}
|
||||
|
||||
OC_JSON::success(array('data' => $result));
|
|
@ -20,6 +20,10 @@ if (empty($_POST['dirToken'])) {
|
|||
die();
|
||||
}
|
||||
} else {
|
||||
// TODO: ideally this code should be in files_sharing/ajax/upload.php
|
||||
// and the upload/file transfer code needs to be refactored into a utility method
|
||||
// that could be used there
|
||||
|
||||
// return only read permissions for public upload
|
||||
$allowedPermissions = OCP\PERMISSION_READ;
|
||||
$public_directory = !empty($_POST['subdir']) ? $_POST['subdir'] : '/';
|
||||
|
@ -141,19 +145,14 @@ if (strpos($dir, '..') === false) {
|
|||
$error = $l->t('The target folder has been moved or deleted.');
|
||||
$errorCode = 'targetnotfound';
|
||||
} else {
|
||||
$result[] = array('status' => 'success',
|
||||
'mime' => $meta['mimetype'],
|
||||
'mtime' => $meta['mtime'],
|
||||
'size' => $meta['size'],
|
||||
'id' => $meta['fileid'],
|
||||
'name' => basename($target),
|
||||
'etag' => $meta['etag'],
|
||||
'originalname' => $files['tmp_name'][$i],
|
||||
'uploadMaxFilesize' => $maxUploadFileSize,
|
||||
'maxHumanFilesize' => $maxHumanFileSize,
|
||||
'permissions' => $meta['permissions'] & $allowedPermissions,
|
||||
'directory' => $directory,
|
||||
);
|
||||
$data = \OCA\Files\Helper::formatFileInfo($meta);
|
||||
$data['status'] = 'success';
|
||||
$data['originalname'] = $files['tmp_name'][$i];
|
||||
$data['uploadMaxFilesize'] = $maxUploadFileSize;
|
||||
$data['maxHumanFilesize'] = $maxHumanFileSize;
|
||||
$data['permissions'] = $meta['permissions'] & $allowedPermissions;
|
||||
$data['directory'] = $directory;
|
||||
$result[] = $data;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -169,19 +168,15 @@ if (strpos($dir, '..') === false) {
|
|||
if ($meta === false) {
|
||||
$error = $l->t('Upload failed. Could not get file info.');
|
||||
} else {
|
||||
$result[] = array('status' => 'existserror',
|
||||
'mime' => $meta['mimetype'],
|
||||
'mtime' => $meta['mtime'],
|
||||
'size' => $meta['size'],
|
||||
'id' => $meta['fileid'],
|
||||
'name' => basename($target),
|
||||
'etag' => $meta['etag'],
|
||||
'originalname' => $files['tmp_name'][$i],
|
||||
'uploadMaxFilesize' => $maxUploadFileSize,
|
||||
'maxHumanFilesize' => $maxHumanFileSize,
|
||||
'permissions' => $meta['permissions'] & $allowedPermissions,
|
||||
'directory' => $directory,
|
||||
);
|
||||
$data = \OCA\Files\Helper::formatFileInfo($meta);
|
||||
$data['permissions'] = $data['permissions'] & $allowedPermissions;
|
||||
$data['status'] = 'existserror';
|
||||
$data['originalname'] = $files['tmp_name'][$i];
|
||||
$data['uploadMaxFilesize'] = $maxUploadFileSize;
|
||||
$data['maxHumanFilesize'] = $maxHumanFileSize;
|
||||
$data['permissions'] = $meta['permissions'] & $allowedPermissions;
|
||||
$data['directory'] = $directory;
|
||||
$result[] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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', 'breadcrumb');
|
||||
OCP\Util::addscript('files', 'filelist');
|
||||
|
||||
OCP\App::setActiveNavigationEntry('files_index');
|
||||
|
@ -60,37 +61,12 @@ if ($isIE8 && isset($_GET['dir'])){
|
|||
exit();
|
||||
}
|
||||
|
||||
$ajaxLoad = false;
|
||||
$files = array();
|
||||
$user = OC_User::getUser();
|
||||
if ($isIE8){
|
||||
// after the redirect above, the URL will have a format
|
||||
// like "files#?dir=path" which means that no path was given
|
||||
// (dir is not set). In that specific case, we don't return any
|
||||
// files because the client will take care of switching the dir
|
||||
// to the one from the hash, then ajax-load the initial file list
|
||||
$files = array();
|
||||
$ajaxLoad = true;
|
||||
}
|
||||
else{
|
||||
$files = \OCA\Files\Helper::getFiles($dir);
|
||||
}
|
||||
|
||||
$config = \OC::$server->getConfig();
|
||||
|
||||
// Make breadcrumb
|
||||
$breadcrumb = \OCA\Files\Helper::makeBreadcrumb($dir);
|
||||
|
||||
// make breadcrumb und filelist markup
|
||||
$list = new OCP\Template('files', 'part.list', '');
|
||||
$list->assign('files', $files);
|
||||
$list->assign('baseURL', OCP\Util::linkTo('files', 'index.php') . '?dir=');
|
||||
$list->assign('downloadURL', OCP\Util::linkToRoute('download', array('file' => '/')));
|
||||
$list->assign('isPublic', false);
|
||||
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
|
||||
$breadcrumbNav->assign('breadcrumb', $breadcrumb);
|
||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkTo('files', 'index.php') . '?dir=');
|
||||
|
||||
// needed for share init, permissions will be reloaded
|
||||
// anyway with ajax load
|
||||
$permissions = $dirInfo->getPermissions();
|
||||
|
||||
// information about storage capacities
|
||||
|
@ -112,20 +88,12 @@ if ($trashEnabled) {
|
|||
$trashEmpty = \OCA\Files_Trashbin\Trashbin::isEmpty($user);
|
||||
}
|
||||
|
||||
$isCreatable = \OC\Files\Filesystem::isCreatable($dir . '/');
|
||||
$fileHeader = (!isset($files) or count($files) > 0);
|
||||
$emptyContent = ($isCreatable and !$fileHeader) or $ajaxLoad;
|
||||
|
||||
OCP\Util::addscript('files', 'fileactions');
|
||||
OCP\Util::addscript('files', 'files');
|
||||
OCP\Util::addscript('files', 'keyboardshortcuts');
|
||||
$tmpl = new OCP\Template('files', 'index', 'user');
|
||||
$tmpl->assign('fileList', $list->fetchPage());
|
||||
$tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage());
|
||||
$tmpl->assign('dir', $dir);
|
||||
$tmpl->assign('isCreatable', $isCreatable);
|
||||
$tmpl->assign('permissions', $permissions);
|
||||
$tmpl->assign('files', $files);
|
||||
$tmpl->assign('trash', $trashEnabled);
|
||||
$tmpl->assign('trashEmpty', $trashEmpty);
|
||||
$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); // minimium of freeSpace and uploadLimit
|
||||
|
@ -141,8 +109,5 @@ $tmpl->assign("mailNotificationEnabled", $config->getAppValue('core', 'shareapi_
|
|||
$tmpl->assign("allowShareWithLink", $config->getAppValue('core', 'shareapi_allow_links', 'yes'));
|
||||
$tmpl->assign("encryptionInitStatus", $encryptionInitStatus);
|
||||
$tmpl->assign('disableSharing', false);
|
||||
$tmpl->assign('ajaxLoad', $ajaxLoad);
|
||||
$tmpl->assign('emptyContent', $emptyContent);
|
||||
$tmpl->assign('fileHeader', $fileHeader);
|
||||
|
||||
$tmpl->printPage();
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
/**
|
||||
* 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 */
|
||||
/* global SVGSupport, replaceSVG */
|
||||
(function() {
|
||||
/**
|
||||
* Creates an breadcrumb element in the given container
|
||||
*/
|
||||
var BreadCrumb = function(options){
|
||||
this.$el = $('<div class="breadcrumb"></div>');
|
||||
options = options || {};
|
||||
if (options.onClick) {
|
||||
this.onClick = options.onClick;
|
||||
}
|
||||
if (options.onDrop) {
|
||||
this.onDrop = options.onDrop;
|
||||
}
|
||||
if (options.getCrumbUrl) {
|
||||
this.getCrumbUrl = options.getCrumbUrl;
|
||||
}
|
||||
};
|
||||
BreadCrumb.prototype = {
|
||||
$el: null,
|
||||
dir: null,
|
||||
|
||||
lastWidth: 0,
|
||||
hiddenBreadcrumbs: 0,
|
||||
totalWidth: 0,
|
||||
breadcrumbs: [],
|
||||
onClick: null,
|
||||
onDrop: null,
|
||||
|
||||
/**
|
||||
* Sets the directory to be displayed as breadcrumb.
|
||||
* This will re-render the breadcrumb.
|
||||
* @param dir path to be displayed as breadcrumb
|
||||
*/
|
||||
setDirectory: function(dir) {
|
||||
dir = dir || '/';
|
||||
if (dir !== this.dir) {
|
||||
this.dir = dir;
|
||||
this.render();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the full URL to the given directory
|
||||
* @param part crumb data as map
|
||||
* @param index crumb index
|
||||
* @return full URL
|
||||
*/
|
||||
getCrumbUrl: function(part, index) {
|
||||
return '#';
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders the breadcrumb elements
|
||||
*/
|
||||
render: function() {
|
||||
var parts = this._makeCrumbs(this.dir || '/');
|
||||
var $crumb;
|
||||
this.$el.empty();
|
||||
this.breadcrumbs = [];
|
||||
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var part = parts[i];
|
||||
var $image;
|
||||
var $link = $('<a></a>').attr('href', this.getCrumbUrl(part, i));
|
||||
$link.text(part.name);
|
||||
$crumb = $('<div class="crumb svg"></div>');
|
||||
$crumb.append($link);
|
||||
$crumb.attr('data-dir', part.dir);
|
||||
|
||||
if (part.img) {
|
||||
$image = $('<img class="svg"></img>');
|
||||
$image.attr('src', part.img);
|
||||
$link.append($image);
|
||||
}
|
||||
this.breadcrumbs.push($crumb);
|
||||
this.$el.append($crumb);
|
||||
if (this.onClick) {
|
||||
$crumb.on('click', this.onClick);
|
||||
}
|
||||
}
|
||||
$crumb.addClass('last');
|
||||
|
||||
// in case svg is not supported by the browser we need to execute the fallback mechanism
|
||||
if (!SVGSupport()) {
|
||||
replaceSVG();
|
||||
}
|
||||
|
||||
// setup drag and drop
|
||||
if (this.onDrop) {
|
||||
this.$el.find('.crumb:not(.last)').droppable({
|
||||
drop: this.onDrop,
|
||||
tolerance: 'pointer'
|
||||
});
|
||||
}
|
||||
|
||||
this._updateTotalWidth();
|
||||
this.resize($(window).width(), true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes a breadcrumb structure based on the given path
|
||||
* @param dir path to split into a breadcrumb structure
|
||||
* @return array of map {dir: path, name: displayName}
|
||||
*/
|
||||
_makeCrumbs: function(dir) {
|
||||
var crumbs = [];
|
||||
var pathToHere = '';
|
||||
// trim leading and trailing slashes
|
||||
dir = dir.replace(/^\/+|\/+$/g, '');
|
||||
var parts = dir.split('/');
|
||||
if (dir === '') {
|
||||
parts = [];
|
||||
}
|
||||
// root part
|
||||
crumbs.push({
|
||||
dir: '/',
|
||||
name: '',
|
||||
img: OC.imagePath('core', 'places/home.svg')
|
||||
});
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var part = parts[i];
|
||||
pathToHere = pathToHere + '/' + part;
|
||||
crumbs.push({
|
||||
dir: pathToHere,
|
||||
name: part
|
||||
});
|
||||
}
|
||||
return crumbs;
|
||||
},
|
||||
|
||||
_updateTotalWidth: function () {
|
||||
var self = this;
|
||||
|
||||
this.lastWidth = 0;
|
||||
|
||||
// initialize with some extra space
|
||||
this.totalWidth = 64;
|
||||
// FIXME: this class should not know about global elements
|
||||
if ( $('#navigation').length ) {
|
||||
this.totalWidth += $('#navigation').get(0).offsetWidth;
|
||||
}
|
||||
this.hiddenBreadcrumbs = 0;
|
||||
|
||||
for (var i = 0; i < this.breadcrumbs.length; i++ ) {
|
||||
this.totalWidth += $(this.breadcrumbs[i]).get(0).offsetWidth;
|
||||
}
|
||||
|
||||
$.each($('#controls .actions>div'), function(index, action) {
|
||||
self.totalWidth += $(action).get(0).offsetWidth;
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Show/hide breadcrumbs to fit the given width
|
||||
*/
|
||||
resize: function (width, firstRun) {
|
||||
var i, $crumb;
|
||||
|
||||
if (width === this.lastWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
// window was shrinked since last time or first run ?
|
||||
if ((width < this.lastWidth || firstRun) && width < this.totalWidth) {
|
||||
if (this.hiddenBreadcrumbs === 0 && this.breadcrumbs.length > 1) {
|
||||
// start by hiding the first breadcrumb after home,
|
||||
// that one will have extra three dots displayed
|
||||
$crumb = this.breadcrumbs[1];
|
||||
this.totalWidth -= $crumb.get(0).offsetWidth;
|
||||
$crumb.find('a').addClass('hidden');
|
||||
$crumb.append('<span class="ellipsis">...</span>');
|
||||
this.totalWidth += $crumb.get(0).offsetWidth;
|
||||
this.hiddenBreadcrumbs = 2;
|
||||
}
|
||||
i = this.hiddenBreadcrumbs;
|
||||
// hide subsequent breadcrumbs if the space is still not enough
|
||||
while (width < this.totalWidth && i > 1 && i < this.breadcrumbs.length - 1) {
|
||||
$crumb = this.breadcrumbs[i];
|
||||
this.totalWidth -= $crumb.get(0).offsetWidth;
|
||||
$crumb.addClass('hidden');
|
||||
this.hiddenBreadcrumbs = i;
|
||||
i++;
|
||||
}
|
||||
// window is bigger than last time
|
||||
} else if (width > this.lastWidth && this.hiddenBreadcrumbs > 0) {
|
||||
i = this.hiddenBreadcrumbs;
|
||||
while (width > this.totalWidth && i > 0) {
|
||||
if (this.hiddenBreadcrumbs === 1) {
|
||||
// special handling for last one as it has the three dots
|
||||
$crumb = this.breadcrumbs[1];
|
||||
if ($crumb) {
|
||||
this.totalWidth -= $crumb.get(0).offsetWidth;
|
||||
$crumb.find('.ellipsis').remove();
|
||||
$crumb.find('a').removeClass('hidden');
|
||||
this.totalWidth += $crumb.get(0).offsetWidth;
|
||||
}
|
||||
} else {
|
||||
$crumb = this.breadcrumbs[i];
|
||||
$crumb.removeClass('hidden');
|
||||
this.totalWidth += $crumb.get(0).offsetWidth;
|
||||
if (this.totalWidth > width) {
|
||||
this.totalWidth -= $crumb.get(0).offsetWidth;
|
||||
$crumb.addClass('hidden');
|
||||
break;
|
||||
}
|
||||
}
|
||||
i--;
|
||||
this.hiddenBreadcrumbs = i;
|
||||
}
|
||||
}
|
||||
|
||||
this.lastWidth = width;
|
||||
}
|
||||
};
|
||||
|
||||
window.BreadCrumb = BreadCrumb;
|
||||
})();
|
||||
|
|
@ -180,7 +180,7 @@ OC.Upload = {
|
|||
},
|
||||
|
||||
init: function() {
|
||||
if ( $('#file_upload_start').exists() && $('#file_upload_start').is(':visible')) {
|
||||
if ( $('#file_upload_start').exists() ) {
|
||||
|
||||
var file_upload_param = {
|
||||
dropZone: $('#content'), // restrict dropZone to content div
|
||||
|
@ -483,28 +483,6 @@ OC.Upload = {
|
|||
$('#file_upload_start').attr('multiple', 'multiple');
|
||||
}
|
||||
|
||||
//if the breadcrumb is to long, start by replacing foldernames with '...' except for the current folder
|
||||
var crumb=$('div.crumb').first();
|
||||
while($('div.controls').height() > 40 && crumb.next('div.crumb').length > 0) {
|
||||
crumb.children('a').text('...');
|
||||
crumb = crumb.next('div.crumb');
|
||||
}
|
||||
//if that isn't enough, start removing items from the breacrumb except for the current folder and it's parent
|
||||
var crumb = $('div.crumb').first();
|
||||
var next = crumb.next('div.crumb');
|
||||
while($('div.controls').height()>40 && next.next('div.crumb').length > 0) {
|
||||
crumb.remove();
|
||||
crumb = next;
|
||||
next = crumb.next('div.crumb');
|
||||
}
|
||||
//still not enough, start shorting down the current folder name
|
||||
var crumb=$('div.crumb>a').last();
|
||||
while($('div.controls').height() > 40 && crumb.text().length > 6) {
|
||||
var text=crumb.text();
|
||||
text = text.substr(0,text.length-6)+'...';
|
||||
crumb.text(text);
|
||||
}
|
||||
|
||||
$(document).click(function(ev) {
|
||||
// do not close when clicking in the dropdown
|
||||
if ($(ev.target).closest('#new').length){
|
||||
|
@ -617,21 +595,7 @@ OC.Upload = {
|
|||
{dir:$('#dir').val(), filename:name},
|
||||
function(result) {
|
||||
if (result.status === 'success') {
|
||||
var date = new Date();
|
||||
// TODO: ideally addFile should be able to receive
|
||||
// all attributes and set them automatically,
|
||||
// and also auto-load the preview
|
||||
var tr = FileList.addFile(name, 0, date, false, hidden);
|
||||
tr.attr('data-size', result.data.size);
|
||||
tr.attr('data-mime', result.data.mime);
|
||||
tr.attr('data-id', result.data.id);
|
||||
tr.attr('data-etag', result.data.etag);
|
||||
tr.find('.filesize').text(humanFileSize(result.data.size));
|
||||
var path = getPathForPreview(name);
|
||||
Files.lazyLoadPreview(path, result.data.mime, function(previewpath) {
|
||||
tr.find('td.filename').attr('style','background-image:url('+previewpath+')');
|
||||
}, null, null, result.data.etag);
|
||||
FileActions.display(tr.find('td.filename'), true);
|
||||
FileList.add(result.data, {hidden: hidden, insert: true});
|
||||
} else {
|
||||
OC.dialogs.alert(result.data.message, t('core', 'Could not create file'));
|
||||
}
|
||||
|
@ -644,10 +608,7 @@ OC.Upload = {
|
|||
{dir:$('#dir').val(), foldername:name},
|
||||
function(result) {
|
||||
if (result.status === 'success') {
|
||||
var date=new Date();
|
||||
FileList.addDir(name, 0, date, hidden);
|
||||
var tr = FileList.findFileEl(name);
|
||||
tr.attr('data-id', result.data.id);
|
||||
FileList.add(result.data, {hidden: hidden, insert: true});
|
||||
} else {
|
||||
OC.dialogs.alert(result.data.message, t('core', 'Could not create folder'));
|
||||
}
|
||||
|
@ -682,20 +643,10 @@ OC.Upload = {
|
|||
}
|
||||
});
|
||||
eventSource.listen('success',function(data) {
|
||||
var mime = data.mime;
|
||||
var size = data.size;
|
||||
var id = data.id;
|
||||
var file = data;
|
||||
$('#uploadprogressbar').fadeOut();
|
||||
var date = new Date();
|
||||
FileList.addFile(localName, size, date, false, hidden);
|
||||
var tr = FileList.findFileEl(localName);
|
||||
tr.data('mime', mime).data('id', id);
|
||||
tr.attr('data-id', id);
|
||||
var path = $('#dir').val()+'/'+localName;
|
||||
Files.lazyLoadPreview(path, mime, function(previewpath) {
|
||||
tr.find('td.filename').attr('style', 'background-image:url('+previewpath+')');
|
||||
}, null, null, data.etag);
|
||||
FileActions.display(tr.find('td.filename'), true);
|
||||
|
||||
FileList.add(file, {hidden: hidden, insert: true});
|
||||
});
|
||||
eventSource.listen('error',function(error) {
|
||||
$('#uploadprogressbar').fadeOut();
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* global OC, FileList */
|
||||
/* global OC, FileList, Files */
|
||||
/* global trashBinApp */
|
||||
var FileActions = {
|
||||
actions: {},
|
||||
|
@ -214,7 +214,7 @@ $(document).ready(function () {
|
|||
FileActions.register(downloadScope, 'Download', OC.PERMISSION_READ, function () {
|
||||
return OC.imagePath('core', 'actions/download');
|
||||
}, function (filename) {
|
||||
var url = FileList.getDownloadUrl(filename);
|
||||
var url = Files.getDownloadUrl(filename);
|
||||
if (url) {
|
||||
OC.redirect(url);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -161,80 +161,33 @@ var Files = {
|
|||
});
|
||||
},
|
||||
|
||||
lastWidth: 0,
|
||||
|
||||
initBreadCrumbs: function () {
|
||||
var $controls = $('#controls');
|
||||
|
||||
Files.lastWidth = 0;
|
||||
Files.breadcrumbs = [];
|
||||
|
||||
// initialize with some extra space
|
||||
Files.breadcrumbsWidth = 64;
|
||||
if ( document.getElementById("navigation") ) {
|
||||
Files.breadcrumbsWidth += $('#navigation').get(0).offsetWidth;
|
||||
/**
|
||||
* Returns the download URL of the given file(s)
|
||||
* @param filename string or array of file names to download
|
||||
* @param dir optional directory in which the file name is, defaults to the current directory
|
||||
*/
|
||||
getDownloadUrl: function(filename, dir) {
|
||||
if ($.isArray(filename)) {
|
||||
filename = JSON.stringify(filename);
|
||||
}
|
||||
Files.hiddenBreadcrumbs = 0;
|
||||
|
||||
$.each($('.crumb'), function(index, breadcrumb) {
|
||||
Files.breadcrumbs[index] = breadcrumb;
|
||||
Files.breadcrumbsWidth += $(breadcrumb).get(0).offsetWidth;
|
||||
});
|
||||
|
||||
$.each($('#controls .actions>div'), function(index, action) {
|
||||
Files.breadcrumbsWidth += $(action).get(0).offsetWidth;
|
||||
});
|
||||
|
||||
// event handlers for breadcrumb items
|
||||
$controls.find('.crumb a').on('click', onClickBreadcrumb);
|
||||
|
||||
// setup drag and drop
|
||||
$controls.find('.crumb:not(.last)').droppable(crumbDropOptions);
|
||||
var params = {
|
||||
dir: dir || FileList.getCurrentDirectory(),
|
||||
files: filename
|
||||
};
|
||||
return this.getAjaxUrl('download', params);
|
||||
},
|
||||
|
||||
resizeBreadcrumbs: function (width, firstRun) {
|
||||
if (width !== Files.lastWidth) {
|
||||
if ((width < Files.lastWidth || firstRun) && width < Files.breadcrumbsWidth) {
|
||||
if (Files.hiddenBreadcrumbs === 0) {
|
||||
bc = $(Files.breadcrumbs[1]).get(0);
|
||||
if (typeof bc != 'undefined') {
|
||||
Files.breadcrumbsWidth -= bc.offsetWidth;
|
||||
$(Files.breadcrumbs[1]).find('a').hide();
|
||||
$(Files.breadcrumbs[1]).append('<span>...</span>');
|
||||
Files.breadcrumbsWidth += bc.offsetWidth;
|
||||
Files.hiddenBreadcrumbs = 2;
|
||||
}
|
||||
}
|
||||
var i = Files.hiddenBreadcrumbs;
|
||||
while (width < Files.breadcrumbsWidth && i > 1 && i < Files.breadcrumbs.length - 1) {
|
||||
Files.breadcrumbsWidth -= $(Files.breadcrumbs[i]).get(0).offsetWidth;
|
||||
$(Files.breadcrumbs[i]).hide();
|
||||
Files.hiddenBreadcrumbs = i;
|
||||
i++;
|
||||
}
|
||||
} else if (width > Files.lastWidth && Files.hiddenBreadcrumbs > 0) {
|
||||
var i = Files.hiddenBreadcrumbs;
|
||||
while (width > Files.breadcrumbsWidth && i > 0) {
|
||||
if (Files.hiddenBreadcrumbs === 1) {
|
||||
Files.breadcrumbsWidth -= $(Files.breadcrumbs[1]).get(0).offsetWidth;
|
||||
$(Files.breadcrumbs[1]).find('span').remove();
|
||||
$(Files.breadcrumbs[1]).find('a').show();
|
||||
Files.breadcrumbsWidth += $(Files.breadcrumbs[1]).get(0).offsetWidth;
|
||||
} else {
|
||||
$(Files.breadcrumbs[i]).show();
|
||||
Files.breadcrumbsWidth += $(Files.breadcrumbs[i]).get(0).offsetWidth;
|
||||
if (Files.breadcrumbsWidth > width) {
|
||||
Files.breadcrumbsWidth -= $(Files.breadcrumbs[i]).get(0).offsetWidth;
|
||||
$(Files.breadcrumbs[i]).hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
i--;
|
||||
Files.hiddenBreadcrumbs = i;
|
||||
}
|
||||
}
|
||||
Files.lastWidth = width;
|
||||
/**
|
||||
* Returns the ajax URL for a given action
|
||||
* @param action action string
|
||||
* @param params optional params map
|
||||
*/
|
||||
getAjaxUrl: function(action, params) {
|
||||
var q = '';
|
||||
if (params) {
|
||||
q = '?' + OC.buildQueryString(params);
|
||||
}
|
||||
return OC.filePath('files', 'ajax', action + '.php') + q;
|
||||
}
|
||||
};
|
||||
$(document).ready(function() {
|
||||
|
@ -245,14 +198,10 @@ $(document).ready(function() {
|
|||
Files.displayEncryptionWarning();
|
||||
Files.bindKeyboardShortcuts(document, jQuery);
|
||||
|
||||
FileList.postProcessList();
|
||||
Files.setupDragAndDrop();
|
||||
|
||||
$('#file_action_panel').attr('activeAction', false);
|
||||
|
||||
// allow dropping on the "files" app icon
|
||||
$('ul#apps li:first-child').data('dir','').droppable(crumbDropOptions);
|
||||
|
||||
// Triggers invisible file input
|
||||
$('#upload a').on('click', function() {
|
||||
$(this).parent().children('#file_upload_start').trigger('click');
|
||||
|
@ -311,7 +260,7 @@ $(document).ready(function() {
|
|||
var filename=$(this).parent().parent().attr('data-file');
|
||||
var tr = FileList.findFileEl(filename);
|
||||
var renaming=tr.data('renaming');
|
||||
if (!renaming && !FileList.isLoading(filename)) {
|
||||
if (!renaming) {
|
||||
FileActions.currentFile = $(this).parent();
|
||||
var mime=FileActions.getCurrentMimeType();
|
||||
var type=FileActions.getCurrentType();
|
||||
|
@ -377,15 +326,15 @@ $(document).ready(function() {
|
|||
dir = OC.dirname(dir) || '/';
|
||||
}
|
||||
else {
|
||||
files = getSelectedFilesTrash('name');
|
||||
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(FileList.getDownloadUrl(files, dir));
|
||||
OC.redirect(Files.getDownloadUrl(files, dir));
|
||||
return false;
|
||||
});
|
||||
|
||||
$('.delete-selected').click(function(event) {
|
||||
var files=getSelectedFilesTrash('name');
|
||||
var files = Files.getSelectedFiles('name');
|
||||
event.preventDefault();
|
||||
if (FileList.isAllSelected()) {
|
||||
files = null;
|
||||
|
@ -403,16 +352,6 @@ $(document).ready(function() {
|
|||
//do a background scan if needed
|
||||
scanFiles();
|
||||
|
||||
Files.initBreadCrumbs();
|
||||
|
||||
$(window).resize(function() {
|
||||
var width = $(this).width();
|
||||
Files.resizeBreadcrumbs(width, false);
|
||||
});
|
||||
|
||||
var width = $(this).width();
|
||||
Files.resizeBreadcrumbs(width, true);
|
||||
|
||||
// display storage warnings
|
||||
setTimeout(Files.displayStorageWarnings, 100);
|
||||
OC.Notification.setDefault(Files.displayStorageWarnings);
|
||||
|
@ -503,7 +442,7 @@ var createDragShadow = function(event) {
|
|||
$(event.target).parents('tr').find('td input:first').prop('checked',true);
|
||||
}
|
||||
|
||||
var selectedFiles = getSelectedFilesTrash();
|
||||
var selectedFiles = Files.getSelectedFiles();
|
||||
|
||||
if (!isDragSelected && selectedFiles.length === 1) {
|
||||
//revert the selection
|
||||
|
@ -619,52 +558,8 @@ var folderDropOptions={
|
|||
tolerance: 'pointer'
|
||||
};
|
||||
|
||||
var crumbDropOptions={
|
||||
drop: function( event, ui ) {
|
||||
var target=$(this).data('dir');
|
||||
var dir = $('#dir').val();
|
||||
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);
|
||||
});
|
||||
});
|
||||
},
|
||||
tolerance: 'pointer'
|
||||
};
|
||||
|
||||
function procesSelection() {
|
||||
var selected = getSelectedFilesTrash();
|
||||
var selected = Files.getSelectedFiles();
|
||||
var selectedFiles = selected.filter(function(el) {
|
||||
return el.type==='file';
|
||||
});
|
||||
|
@ -714,7 +609,7 @@ function procesSelection() {
|
|||
* 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
|
||||
*/
|
||||
function getSelectedFilesTrash(property) {
|
||||
Files.getSelectedFiles = function(property) {
|
||||
var elements=$('td.filename input:checkbox:checked').parent().parent();
|
||||
var files=[];
|
||||
elements.each(function(i,element) {
|
||||
|
@ -755,25 +650,30 @@ function getPathForPreview(name) {
|
|||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a preview URL based on the URL space.
|
||||
* @param urlSpec map with {x: width, y: height, file: file path}
|
||||
* @return preview URL
|
||||
*/
|
||||
Files.generatePreviewUrl = function(urlSpec) {
|
||||
urlSpec = urlSpec || {};
|
||||
if (!urlSpec.x) {
|
||||
urlSpec.x = $('#filestable').data('preview-x');
|
||||
}
|
||||
if (!urlSpec.y) {
|
||||
urlSpec.y = $('#filestable').data('preview-y');
|
||||
}
|
||||
urlSpec.forceIcon = 0;
|
||||
return OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
|
||||
}
|
||||
|
||||
Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
|
||||
// get mime icon url
|
||||
Files.getMimeIcon(mime, function(iconURL) {
|
||||
var urlSpec = {};
|
||||
var previewURL;
|
||||
urlSpec = {};
|
||||
ready(iconURL); // set mimeicon URL
|
||||
|
||||
// now try getting a preview thumbnail URL
|
||||
if ( ! width ) {
|
||||
width = $('#filestable').data('preview-x');
|
||||
}
|
||||
if ( ! height ) {
|
||||
height = $('#filestable').data('preview-y');
|
||||
}
|
||||
// note: the order of arguments must match the one
|
||||
// from the server's template so that the browser
|
||||
// knows it's the same file for caching
|
||||
urlSpec.x = width;
|
||||
urlSpec.y = height;
|
||||
urlSpec.file = Files.fixPath(path);
|
||||
|
||||
if (etag){
|
||||
|
@ -784,15 +684,9 @@ Files.lazyLoadPreview = function(path, mime, ready, width, height, etag) {
|
|||
console.warn('Files.lazyLoadPreview(): missing etag argument');
|
||||
}
|
||||
|
||||
if ( $('#isPublic').length ) {
|
||||
urlSpec.t = $('#dirToken').val();
|
||||
previewURL = OC.generateUrl('/publicpreview.png?') + $.param(urlSpec);
|
||||
} else {
|
||||
previewURL = OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
|
||||
}
|
||||
previewURL = Files.generatePreviewUrl(urlSpec);
|
||||
previewURL = previewURL.replace('(', '%28');
|
||||
previewURL = previewURL.replace(')', '%29');
|
||||
previewURL += '&forceIcon=0';
|
||||
|
||||
// preload image to prevent delay
|
||||
// this will make the browser cache the image
|
||||
|
@ -841,14 +735,8 @@ function checkTrashStatus() {
|
|||
});
|
||||
}
|
||||
|
||||
function onClickBreadcrumb(e) {
|
||||
var $el = $(e.target).closest('.crumb'),
|
||||
$targetDir = $el.data('dir'),
|
||||
isPublic = !!$('#isPublic').val();
|
||||
|
||||
if ($targetDir !== undefined && !isPublic) {
|
||||
e.preventDefault();
|
||||
FileList.changeDirectory(decodeURIComponent($targetDir));
|
||||
}
|
||||
// override core's fileDownloadPath (legacy)
|
||||
function fileDownloadPath(dir, file) {
|
||||
return Files.getDownloadUrl(file, dir);
|
||||
}
|
||||
|
||||
|
|
|
@ -84,25 +84,7 @@ class App {
|
|||
) {
|
||||
// successful rename
|
||||
$meta = $this->view->getFileInfo($dir . '/' . $newname);
|
||||
if ($meta['mimetype'] === 'httpd/unix-directory') {
|
||||
$meta['type'] = 'dir';
|
||||
}
|
||||
else {
|
||||
$meta['type'] = 'file';
|
||||
}
|
||||
// these need to be set for determineIcon()
|
||||
$meta['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($meta['mimetype']);
|
||||
$meta['directory'] = $dir;
|
||||
$fileinfo = array(
|
||||
'id' => $meta['fileid'],
|
||||
'mime' => $meta['mimetype'],
|
||||
'size' => $meta['size'],
|
||||
'etag' => $meta['etag'],
|
||||
'directory' => $meta['directory'],
|
||||
'name' => $newname,
|
||||
'isPreviewAvailable' => $meta['isPreviewAvailable'],
|
||||
'icon' => \OCA\Files\Helper::determineIcon($meta)
|
||||
);
|
||||
$fileinfo = \OCA\Files\Helper::formatFileInfo($meta);
|
||||
$result['success'] = true;
|
||||
$result['data'] = $fileinfo;
|
||||
} else {
|
||||
|
|
|
@ -19,11 +19,17 @@ class Helper
|
|||
'usedSpacePercent' => (int)$storageInfo['relative']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine icon for a given file
|
||||
*
|
||||
* @param \OC\Files\FileInfo $file file info
|
||||
* @return string icon URL
|
||||
*/
|
||||
public static function determineIcon($file) {
|
||||
if($file['type'] === 'dir') {
|
||||
$dir = $file['directory'];
|
||||
$icon = \OC_Helper::mimetypeIcon('dir');
|
||||
$absPath = \OC\Files\Filesystem::getView()->getAbsolutePath($dir.'/'.$file['name']);
|
||||
$absPath = $file->getPath();
|
||||
$mount = \OC\Files\Filesystem::getMountManager()->find($absPath);
|
||||
if (!is_null($mount)) {
|
||||
$sid = $mount->getStorageId();
|
||||
|
@ -38,11 +44,7 @@ class Helper
|
|||
}
|
||||
}
|
||||
}else{
|
||||
if($file['isPreviewAvailable']) {
|
||||
$pathForPreview = $file['directory'] . '/' . $file['name'];
|
||||
return \OC_Helper::previewIcon($pathForPreview) . '&c=' . $file['etag'];
|
||||
}
|
||||
$icon = \OC_Helper::mimetypeIcon($file['mimetype']);
|
||||
$icon = \OC_Helper::mimetypeIcon($file->getMimetype());
|
||||
}
|
||||
|
||||
return substr($icon, 0, -3) . 'svg';
|
||||
|
@ -69,52 +71,58 @@ class Helper
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieves the contents of the given directory and
|
||||
* returns it as a sorted array.
|
||||
* @param string $dir path to the directory
|
||||
* @return array of files
|
||||
* Formats the file info to be returned as JSON to the client.
|
||||
*
|
||||
* @param \OCP\Files\FileInfo file info
|
||||
* @return array formatted file info
|
||||
*/
|
||||
public static function getFiles($dir) {
|
||||
$content = \OC\Files\Filesystem::getDirectoryContent($dir);
|
||||
$files = array();
|
||||
public static function formatFileInfo($i) {
|
||||
$entry = array();
|
||||
|
||||
foreach ($content as $i) {
|
||||
$i['date'] = \OCP\Util::formatDate($i['mtime']);
|
||||
if ($i['type'] === 'file') {
|
||||
$fileinfo = pathinfo($i['name']);
|
||||
$i['basename'] = $fileinfo['filename'];
|
||||
if (!empty($fileinfo['extension'])) {
|
||||
$i['extension'] = '.' . $fileinfo['extension'];
|
||||
} else {
|
||||
$i['extension'] = '';
|
||||
}
|
||||
}
|
||||
$i['directory'] = $dir;
|
||||
$i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($i['mimetype']);
|
||||
$i['icon'] = \OCA\Files\Helper::determineIcon($i);
|
||||
$files[] = $i;
|
||||
$entry['id'] = $i['fileid'];
|
||||
$entry['date'] = \OCP\Util::formatDate($i['mtime']);
|
||||
$entry['mtime'] = $i['mtime'] * 1000;
|
||||
// only pick out the needed attributes
|
||||
$entry['icon'] = \OCA\Files\Helper::determineIcon($i);
|
||||
if (\OC::$server->getPreviewManager()->isMimeSupported($i['mimetype'])) {
|
||||
$entry['isPreviewAvailable'] = true;
|
||||
}
|
||||
$entry['name'] = $i['name'];
|
||||
$entry['permissions'] = $i['permissions'];
|
||||
$entry['mimetype'] = $i['mimetype'];
|
||||
$entry['size'] = $i['size'];
|
||||
$entry['type'] = $i['type'];
|
||||
$entry['etag'] = $i['etag'];
|
||||
if (isset($i['displayname_owner'])) {
|
||||
$entry['shareOwner'] = $i['displayname_owner'];
|
||||
}
|
||||
return $entry;
|
||||
}
|
||||
|
||||
usort($files, array('\OCA\Files\Helper', 'fileCmp'));
|
||||
/**
|
||||
* Format file info for JSON
|
||||
* @param \OCP\Files\FileInfo[] $fileInfos file infos
|
||||
*/
|
||||
public static function formatFileInfos($fileInfos) {
|
||||
$files = array();
|
||||
foreach ($fileInfos as $i) {
|
||||
$files[] = self::formatFileInfo($i);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the given path into a breadcrumb structure.
|
||||
* @param string $dir path to process
|
||||
* @return array where each entry is a hash of the absolute
|
||||
* directory path and its name
|
||||
* Retrieves the contents of the given directory and
|
||||
* returns it as a sorted array of FileInfo.
|
||||
*
|
||||
* @param string $dir path to the directory
|
||||
* @return \OCP\Files\FileInfo[] files
|
||||
*/
|
||||
public static function makeBreadcrumb($dir){
|
||||
$breadcrumb = array();
|
||||
$pathtohere = '';
|
||||
foreach (explode('/', $dir) as $i) {
|
||||
if ($i !== '') {
|
||||
$pathtohere .= '/' . $i;
|
||||
$breadcrumb[] = array('dir' => $pathtohere, 'name' => $i);
|
||||
}
|
||||
}
|
||||
return $breadcrumb;
|
||||
public static function getFiles($dir) {
|
||||
$content = \OC\Files\Filesystem::getDirectoryContent($dir);
|
||||
|
||||
usort($content, array('\OCA\Files\Helper', 'fileCmp'));
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<div id="controls">
|
||||
<?php print_unescaped($_['breadcrumb']); ?>
|
||||
<div class="actions creatable <?php if (!$_['isCreatable']):?>hidden<?php endif; ?>">
|
||||
<div class="actions creatable hidden">
|
||||
<?php if(!isset($_['dirToken'])):?>
|
||||
<div id="new" class="button">
|
||||
<a><?php p($l->t('New'));?></a>
|
||||
|
@ -48,20 +47,20 @@
|
|||
</div>
|
||||
</div>
|
||||
<div id="file_action_panel"></div>
|
||||
<div class="notCreatable notPublic <?php if ($_['isCreatable'] or $_['isPublic'] ):?>hidden<?php endif; ?>">
|
||||
<div class="notCreatable notPublic hidden">
|
||||
<?php p($l->t('You don’t have permission to upload or create files here'))?>
|
||||
</div>
|
||||
<input type="hidden" name="permissions" value="<?php p($_['permissions']); ?>" id="permissions">
|
||||
</div>
|
||||
|
||||
<div id="emptycontent" <?php if (!$_['emptyContent']):?>class="hidden"<?php endif; ?>><?php p($l->t('Nothing in here. Upload something!'))?></div>
|
||||
<div id="emptycontent" class="hidden"><?php p($l->t('Nothing in here. Upload something!'))?></div>
|
||||
|
||||
<input type="hidden" id="disableSharing" data-status="<?php p($_['disableSharing']); ?>" />
|
||||
|
||||
<table id="filestable" data-allow-public-upload="<?php p($_['publicUploadEnabled'])?>" data-preview-x="36" data-preview-y="36">
|
||||
<thead>
|
||||
<tr>
|
||||
<th <?php if (!$_['fileHeader']):?>class="hidden"<?php endif; ?> id='headerName'>
|
||||
<th class="hidden" id='headerName'>
|
||||
<div id="headerName-container">
|
||||
<input type="checkbox" id="select_all" />
|
||||
<label for="select_all"></label>
|
||||
|
@ -77,8 +76,8 @@
|
|||
</span>
|
||||
</div>
|
||||
</th>
|
||||
<th <?php if (!$_['fileHeader']):?>class="hidden"<?php endif; ?> id="headerSize"><?php p($l->t('Size')); ?></th>
|
||||
<th <?php if (!$_['fileHeader']):?>class="hidden"<?php endif; ?> id="headerDate">
|
||||
<th class="hidden" id="headerSize"><?php p($l->t('Size')); ?></th>
|
||||
<th class="hidden" id="headerDate">
|
||||
<span id="modified"><?php p($l->t( 'Modified' )); ?></span>
|
||||
<?php if ($_['permissions'] & OCP\PERMISSION_DELETE): ?>
|
||||
<span class="selectedActions"><a href="" class="delete-selected">
|
||||
|
@ -91,7 +90,6 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody id="fileList">
|
||||
<?php print_unescaped($_['fileList']); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="editor"></div><!-- FIXME Do not use this div in your app! It is deprecated and will be removed in the future! -->
|
||||
|
@ -111,7 +109,6 @@
|
|||
|
||||
<!-- config hints for javascript -->
|
||||
<input type="hidden" name="filesApp" id="filesApp" value="1" />
|
||||
<input type="hidden" name="ajaxLoad" id="ajaxLoad" value="<?php p($_['ajaxLoad']); ?>" />
|
||||
<input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php p($_['allowZipDownload']); ?>" />
|
||||
<input type="hidden" name="usedSpacePercent" id="usedSpacePercent" value="<?php p($_['usedSpacePercent']); ?>" />
|
||||
<?php if (!$_['isPublic']) :?>
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
<div class="crumb svg <?php if(!count($_["breadcrumb"])) p('last');?>" data-dir=''>
|
||||
<a href="<?php print_unescaped($_['baseURL']); ?>">
|
||||
<?php if(isset($_['rootBreadCrumb'])):
|
||||
echo $_['rootBreadCrumb'];
|
||||
else:?>
|
||||
<img src="<?php print_unescaped(OCP\image_path('core', 'places/home.svg'));?>" class="svg" />
|
||||
<?php endif;?>
|
||||
</a>
|
||||
</div>
|
||||
<?php for($i=0; $i<count($_["breadcrumb"]); $i++):
|
||||
$crumb = $_["breadcrumb"][$i];
|
||||
$dir = \OCP\Util::encodePath($crumb["dir"]); ?>
|
||||
<div class="crumb <?php if($i == count($_["breadcrumb"])-1) p('last');?> svg"
|
||||
data-dir='<?php p($dir);?>'>
|
||||
<a href="<?php p($_['baseURL'].$dir); ?>"><?php p($crumb["name"]); ?></a>
|
||||
</div>
|
||||
<?php endfor;
|
|
@ -1,67 +0,0 @@
|
|||
<?php $totalfiles = 0;
|
||||
$totaldirs = 0;
|
||||
$totalsize = 0; ?>
|
||||
<?php foreach($_['files'] as $file):
|
||||
// the bigger the file, the darker the shade of grey; megabytes*2
|
||||
$simple_size_color = intval(160-$file['size']/(1024*1024)*2);
|
||||
if($simple_size_color<0) $simple_size_color = 0;
|
||||
$relative_modified_date = OCP\relative_modified_date($file['mtime']);
|
||||
// the older the file, the brighter the shade of grey; days*14
|
||||
$relative_date_color = round((time()-$file['mtime'])/60/60/24*14);
|
||||
if($relative_date_color>160) $relative_date_color = 160;
|
||||
$name = \OCP\Util::encodePath($file['name']);
|
||||
$directory = \OCP\Util::encodePath($file['directory']); ?>
|
||||
<tr data-id="<?php p($file['fileid']); ?>"
|
||||
data-file="<?php p($name);?>"
|
||||
data-type="<?php ($file['type'] == 'dir')?p('dir'):p('file')?>"
|
||||
data-mime="<?php p($file['mimetype'])?>"
|
||||
data-size="<?php p($file['size']);?>"
|
||||
data-etag="<?php p($file['etag']);?>"
|
||||
data-permissions="<?php p($file['permissions']); ?>"
|
||||
|
||||
<?php if(isset($file['displayname_owner'])): ?>
|
||||
data-share-owner="<?php p($file['displayname_owner']) ?>"
|
||||
<?php endif; ?>
|
||||
>
|
||||
|
||||
<?php if(isset($file['isPreviewAvailable']) and $file['isPreviewAvailable']): ?>
|
||||
<td class="filename svg preview-icon"
|
||||
<?php else: ?>
|
||||
<td class="filename svg"
|
||||
<?php endif; ?>
|
||||
style="background-image:url(<?php print_unescaped($file['icon']); ?>)"
|
||||
>
|
||||
<?php if(!isset($_['readonly']) || !$_['readonly']): ?>
|
||||
<input id="select-<?php p($file['fileid']); ?>" type="checkbox" />
|
||||
<label for="select-<?php p($file['fileid']); ?>"></label>
|
||||
<?php endif; ?>
|
||||
<?php if($file['type'] == 'dir'): ?>
|
||||
<a class="name" href="<?php p(rtrim($_['baseURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>" title="">
|
||||
<span class="nametext">
|
||||
<?php print_unescaped(htmlspecialchars($file['name']));?>
|
||||
</span>
|
||||
<span class="uploadtext" currentUploads="0">
|
||||
</span>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<a class="name" href="<?php p(rtrim($_['downloadURL'],'/').'/'.trim($directory,'/').'/'.$name); ?>">
|
||||
<label class="filetext" title="" for="select-<?php p($file['fileid']); ?>"></label>
|
||||
<span class="nametext"><?php print_unescaped(htmlspecialchars($file['basename']));?><span class='extension'><?php p($file['extension']);?></span></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="filesize"
|
||||
style="color:rgb(<?php p($simple_size_color.','.$simple_size_color.','.$simple_size_color) ?>)">
|
||||
<?php print_unescaped(OCP\human_file_size($file['size'])); ?>
|
||||
</td>
|
||||
<td class="date">
|
||||
<span class="modified"
|
||||
title="<?php p($file['date']); ?>"
|
||||
style="color:rgb(<?php p($relative_date_color.','
|
||||
.$relative_date_color.','
|
||||
.$relative_date_color) ?>)">
|
||||
<?php p($relative_modified_date); ?>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;
|
|
@ -92,28 +92,32 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
|
|||
|
||||
$this->viewMock->expects($this->any())
|
||||
->method('getFileInfo')
|
||||
->will($this->returnValue(array(
|
||||
->will($this->returnValue(new \OC\Files\FileInfo(
|
||||
'/test',
|
||||
null,
|
||||
'/test',
|
||||
array(
|
||||
'fileid' => 123,
|
||||
'type' => 'dir',
|
||||
'mimetype' => 'httpd/unix-directory',
|
||||
'mtime' => 0,
|
||||
'permissions' => 31,
|
||||
'size' => 18,
|
||||
'etag' => 'abcdef',
|
||||
'directory' => '/',
|
||||
'name' => 'new_name',
|
||||
)));
|
||||
))));
|
||||
|
||||
$result = $this->files->rename($dir, $oldname, $newname);
|
||||
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertEquals(123, $result['data']['id']);
|
||||
$this->assertEquals('new_name', $result['data']['name']);
|
||||
$this->assertEquals('/test', $result['data']['directory']);
|
||||
$this->assertEquals(18, $result['data']['size']);
|
||||
$this->assertEquals('httpd/unix-directory', $result['data']['mime']);
|
||||
$this->assertEquals('httpd/unix-directory', $result['data']['mimetype']);
|
||||
$icon = \OC_Helper::mimetypeIcon('dir');
|
||||
$icon = substr($icon, 0, -3) . 'svg';
|
||||
$this->assertEquals($icon, $result['data']['icon']);
|
||||
$this->assertFalse($result['data']['isPreviewAvailable']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,29 +152,33 @@ class Test_OC_Files_App_Rename extends \PHPUnit_Framework_TestCase {
|
|||
|
||||
$this->viewMock->expects($this->any())
|
||||
->method('getFileInfo')
|
||||
->will($this->returnValue(array(
|
||||
->will($this->returnValue(new \OC\Files\FileInfo(
|
||||
'/',
|
||||
null,
|
||||
'/',
|
||||
array(
|
||||
'fileid' => 123,
|
||||
'type' => 'dir',
|
||||
'mimetype' => 'httpd/unix-directory',
|
||||
'mtime' => 0,
|
||||
'permissions' => 31,
|
||||
'size' => 18,
|
||||
'etag' => 'abcdef',
|
||||
'directory' => '/',
|
||||
'name' => 'new_name',
|
||||
)));
|
||||
))));
|
||||
|
||||
$result = $this->files->rename($dir, $oldname, $newname);
|
||||
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertEquals(123, $result['data']['id']);
|
||||
$this->assertEquals('newname', $result['data']['name']);
|
||||
$this->assertEquals('/', $result['data']['directory']);
|
||||
$this->assertEquals('new_name', $result['data']['name']);
|
||||
$this->assertEquals(18, $result['data']['size']);
|
||||
$this->assertEquals('httpd/unix-directory', $result['data']['mime']);
|
||||
$this->assertEquals('httpd/unix-directory', $result['data']['mimetype']);
|
||||
$this->assertEquals('abcdef', $result['data']['etag']);
|
||||
$icon = \OC_Helper::mimetypeIcon('dir');
|
||||
$icon = substr($icon, 0, -3) . 'svg';
|
||||
$this->assertEquals($icon, $result['data']['icon']);
|
||||
$this->assertFalse($result['data']['isPreviewAvailable']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
/**
|
||||
* 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 BreadCrumb */
|
||||
describe('BreadCrumb tests', function() {
|
||||
describe('Rendering', function() {
|
||||
var bc;
|
||||
beforeEach(function() {
|
||||
bc = new BreadCrumb({
|
||||
getCrumbUrl: function(part, index) {
|
||||
// for testing purposes
|
||||
return part.dir + '#' + index;
|
||||
}
|
||||
});
|
||||
});
|
||||
afterEach(function() {
|
||||
bc = null;
|
||||
});
|
||||
it('Renders its own container', function() {
|
||||
bc.render();
|
||||
expect(bc.$el.hasClass('breadcrumb')).toEqual(true);
|
||||
});
|
||||
it('Renders root by default', function() {
|
||||
var $crumbs;
|
||||
bc.render();
|
||||
$crumbs = bc.$el.find('.crumb');
|
||||
expect($crumbs.length).toEqual(1);
|
||||
expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0');
|
||||
expect($crumbs.eq(0).find('img').length).toEqual(1);
|
||||
expect($crumbs.eq(0).attr('data-dir')).toEqual('/');
|
||||
});
|
||||
it('Renders root when switching to root', function() {
|
||||
var $crumbs;
|
||||
bc.setDirectory('/somedir');
|
||||
bc.setDirectory('/');
|
||||
$crumbs = bc.$el.find('.crumb');
|
||||
expect($crumbs.length).toEqual(1);
|
||||
expect($crumbs.eq(0).attr('data-dir')).toEqual('/');
|
||||
});
|
||||
it('Renders last crumb with "last" class', function() {
|
||||
bc.setDirectory('/abc/def');
|
||||
expect(bc.$el.find('.crumb:last').hasClass('last')).toEqual(true);
|
||||
});
|
||||
it('Renders single path section', function() {
|
||||
var $crumbs;
|
||||
bc.setDirectory('/somedir');
|
||||
$crumbs = bc.$el.find('.crumb');
|
||||
expect($crumbs.length).toEqual(2);
|
||||
expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0');
|
||||
expect($crumbs.eq(0).find('img').length).toEqual(1);
|
||||
expect($crumbs.eq(0).attr('data-dir')).toEqual('/');
|
||||
expect($crumbs.eq(1).find('a').attr('href')).toEqual('/somedir#1');
|
||||
expect($crumbs.eq(1).find('img').length).toEqual(0);
|
||||
expect($crumbs.eq(1).attr('data-dir')).toEqual('/somedir');
|
||||
});
|
||||
it('Renders multiple path sections and special chars', function() {
|
||||
var $crumbs;
|
||||
bc.setDirectory('/somedir/with space/abc');
|
||||
$crumbs = bc.$el.find('.crumb');
|
||||
expect($crumbs.length).toEqual(4);
|
||||
expect($crumbs.eq(0).find('a').attr('href')).toEqual('/#0');
|
||||
expect($crumbs.eq(0).find('img').length).toEqual(1);
|
||||
expect($crumbs.eq(0).attr('data-dir')).toEqual('/');
|
||||
|
||||
expect($crumbs.eq(1).find('a').attr('href')).toEqual('/somedir#1');
|
||||
expect($crumbs.eq(1).find('img').length).toEqual(0);
|
||||
expect($crumbs.eq(1).attr('data-dir')).toEqual('/somedir');
|
||||
|
||||
expect($crumbs.eq(2).find('a').attr('href')).toEqual('/somedir/with space#2');
|
||||
expect($crumbs.eq(2).find('img').length).toEqual(0);
|
||||
expect($crumbs.eq(2).attr('data-dir')).toEqual('/somedir/with space');
|
||||
|
||||
expect($crumbs.eq(3).find('a').attr('href')).toEqual('/somedir/with space/abc#3');
|
||||
expect($crumbs.eq(3).find('img').length).toEqual(0);
|
||||
expect($crumbs.eq(3).attr('data-dir')).toEqual('/somedir/with space/abc');
|
||||
});
|
||||
});
|
||||
describe('Events', function() {
|
||||
it('Calls onClick handler when clicking on a crumb', function() {
|
||||
var handler = sinon.stub();
|
||||
var bc = new BreadCrumb({
|
||||
onClick: handler
|
||||
});
|
||||
bc.setDirectory('/one/two/three/four');
|
||||
bc.$el.find('.crumb:eq(3)').click();
|
||||
expect(handler.calledOnce).toEqual(true);
|
||||
expect(handler.getCall(0).thisValue).toEqual(bc.$el.find('.crumb').get(3));
|
||||
|
||||
handler.reset();
|
||||
bc.$el.find('.crumb:eq(0) a').click();
|
||||
expect(handler.calledOnce).toEqual(true);
|
||||
expect(handler.getCall(0).thisValue).toEqual(bc.$el.find('.crumb').get(0));
|
||||
});
|
||||
it('Calls onDrop handler when dropping on a crumb', function() {
|
||||
var droppableStub = sinon.stub($.fn, 'droppable');
|
||||
var handler = sinon.stub();
|
||||
var bc = new BreadCrumb({
|
||||
onDrop: handler
|
||||
});
|
||||
bc.setDirectory('/one/two/three/four');
|
||||
expect(droppableStub.calledOnce).toEqual(true);
|
||||
|
||||
expect(droppableStub.getCall(0).args[0].drop).toBeDefined();
|
||||
// simulate drop
|
||||
droppableStub.getCall(0).args[0].drop({dummy: true});
|
||||
|
||||
expect(handler.calledOnce).toEqual(true);
|
||||
expect(handler.getCall(0).args[0]).toEqual({dummy: true});
|
||||
|
||||
droppableStub.restore();
|
||||
});
|
||||
});
|
||||
describe('Resizing', function() {
|
||||
var bc, widthStub, dummyDir,
|
||||
oldUpdateTotalWidth;
|
||||
|
||||
beforeEach(function() {
|
||||
dummyDir = '/short name/longer name/looooooooooooonger/even longer long long long longer long/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/last one';
|
||||
|
||||
oldUpdateTotalWidth = BreadCrumb.prototype._updateTotalWidth;
|
||||
BreadCrumb.prototype._updateTotalWidth = function() {
|
||||
// need to set display:block for correct offsetWidth (no CSS loaded here)
|
||||
$('div.crumb').css({
|
||||
'display': 'block',
|
||||
'float': 'left'
|
||||
});
|
||||
|
||||
return oldUpdateTotalWidth.apply(this, arguments);
|
||||
};
|
||||
|
||||
bc = new BreadCrumb();
|
||||
widthStub = sinon.stub($.fn, 'width');
|
||||
// append dummy navigation and controls
|
||||
// as they are currently used for measurements
|
||||
$('#testArea').append(
|
||||
'<div id="navigation" style="width: 80px"></div>',
|
||||
'<div id="controls"></div>'
|
||||
);
|
||||
|
||||
// make sure we know the test screen width
|
||||
$('#testArea').css('width', 1280);
|
||||
|
||||
// use test area as we need it for measurements
|
||||
$('#controls').append(bc.$el);
|
||||
$('#controls').append('<div class="actions"><div>Dummy action with a given width</div></div>');
|
||||
});
|
||||
afterEach(function() {
|
||||
BreadCrumb.prototype._updateTotalWidth = oldUpdateTotalWidth;
|
||||
widthStub.restore();
|
||||
bc = null;
|
||||
});
|
||||
it('Hides breadcrumbs to fit window', function() {
|
||||
var $crumbs;
|
||||
|
||||
widthStub.returns(500);
|
||||
// triggers resize implicitly
|
||||
bc.setDirectory(dummyDir);
|
||||
$crumbs = bc.$el.find('.crumb');
|
||||
|
||||
// first one is always visible
|
||||
expect($crumbs.eq(0).hasClass('hidden')).toEqual(false);
|
||||
// second one has ellipsis
|
||||
expect($crumbs.eq(1).hasClass('hidden')).toEqual(false);
|
||||
expect($crumbs.eq(1).find('.ellipsis').length).toEqual(1);
|
||||
// there is only one ellipsis in total
|
||||
expect($crumbs.find('.ellipsis').length).toEqual(1);
|
||||
// subsequent elements are hidden
|
||||
expect($crumbs.eq(2).hasClass('hidden')).toEqual(true);
|
||||
expect($crumbs.eq(3).hasClass('hidden')).toEqual(true);
|
||||
expect($crumbs.eq(4).hasClass('hidden')).toEqual(true);
|
||||
expect($crumbs.eq(5).hasClass('hidden')).toEqual(true);
|
||||
expect($crumbs.eq(6).hasClass('hidden')).toEqual(false);
|
||||
});
|
||||
it('Updates ellipsis on window size increase', function() {
|
||||
var $crumbs;
|
||||
|
||||
widthStub.returns(500);
|
||||
// triggers resize implicitly
|
||||
bc.setDirectory(dummyDir);
|
||||
$crumbs = bc.$el.find('.crumb');
|
||||
|
||||
// simulate increase
|
||||
$('#testArea').css('width', 1800);
|
||||
bc.resize(1800);
|
||||
|
||||
// first one is always visible
|
||||
expect($crumbs.eq(0).hasClass('hidden')).toEqual(false);
|
||||
// second one has ellipsis
|
||||
expect($crumbs.eq(1).hasClass('hidden')).toEqual(false);
|
||||
expect($crumbs.eq(1).find('.ellipsis').length).toEqual(1);
|
||||
// there is only one ellipsis in total
|
||||
expect($crumbs.find('.ellipsis').length).toEqual(1);
|
||||
// subsequent elements are hidden
|
||||
expect($crumbs.eq(2).hasClass('hidden')).toEqual(true);
|
||||
expect($crumbs.eq(3).hasClass('hidden')).toEqual(true);
|
||||
expect($crumbs.eq(4).hasClass('hidden')).toEqual(true);
|
||||
// the rest is visible
|
||||
expect($crumbs.eq(5).hasClass('hidden')).toEqual(false);
|
||||
expect($crumbs.eq(6).hasClass('hidden')).toEqual(false);
|
||||
});
|
||||
it('Updates ellipsis on window size decrease', function() {
|
||||
var $crumbs;
|
||||
|
||||
$('#testArea').css('width', 2000);
|
||||
widthStub.returns(2000);
|
||||
// triggers resize implicitly
|
||||
bc.setDirectory(dummyDir);
|
||||
$crumbs = bc.$el.find('.crumb');
|
||||
|
||||
// simulate decrease
|
||||
bc.resize(500);
|
||||
$('#testArea').css('width', 500);
|
||||
|
||||
// first one is always visible
|
||||
expect($crumbs.eq(0).hasClass('hidden')).toEqual(false);
|
||||
// second one has ellipsis
|
||||
expect($crumbs.eq(1).hasClass('hidden')).toEqual(false);
|
||||
expect($crumbs.eq(1).find('.ellipsis').length).toEqual(1);
|
||||
// there is only one ellipsis in total
|
||||
expect($crumbs.find('.ellipsis').length).toEqual(1);
|
||||
// subsequent elements are hidden
|
||||
expect($crumbs.eq(2).hasClass('hidden')).toEqual(true);
|
||||
expect($crumbs.eq(3).hasClass('hidden')).toEqual(true);
|
||||
expect($crumbs.eq(4).hasClass('hidden')).toEqual(true);
|
||||
// the rest is visible
|
||||
expect($crumbs.eq(5).hasClass('hidden')).toEqual(true);
|
||||
expect($crumbs.eq(6).hasClass('hidden')).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -22,6 +22,7 @@
|
|||
/* global OC, FileActions, FileList */
|
||||
describe('FileActions tests', function() {
|
||||
var $filesTable;
|
||||
|
||||
beforeEach(function() {
|
||||
// init horrible parameters
|
||||
var $body = $('body');
|
||||
|
@ -34,17 +35,20 @@ describe('FileActions tests', function() {
|
|||
$('#dir, #permissions, #filestable').remove();
|
||||
});
|
||||
it('calling display() sets file actions', function() {
|
||||
// note: download_url is actually the link target, not the actual download URL...
|
||||
var $tr = FileList.addFile('testName.txt', 1234, new Date(), false, false, {download_url: 'test/download/url'});
|
||||
var fileData = {
|
||||
id: 18,
|
||||
type: 'file',
|
||||
name: 'testName.txt',
|
||||
mimetype: 'plain/text',
|
||||
size: '1234',
|
||||
etag: 'a01234c',
|
||||
mtime: '123456'
|
||||
};
|
||||
|
||||
// no actions before call
|
||||
expect($tr.find('.action.action-download').length).toEqual(0);
|
||||
expect($tr.find('.action.action-rename').length).toEqual(0);
|
||||
expect($tr.find('.action.delete').length).toEqual(0);
|
||||
// note: FileActions.display() is called implicitly
|
||||
var $tr = FileList.add(fileData);
|
||||
|
||||
FileActions.display($tr.find('td.filename'), true);
|
||||
|
||||
// actions defined after cal
|
||||
// actions defined after call
|
||||
expect($tr.find('.action.action-download').length).toEqual(1);
|
||||
expect($tr.find('.action.action-download').attr('data-action')).toEqual('Download');
|
||||
expect($tr.find('.nametext .action.action-rename').length).toEqual(1);
|
||||
|
@ -52,7 +56,16 @@ describe('FileActions tests', function() {
|
|||
expect($tr.find('.action.delete').length).toEqual(1);
|
||||
});
|
||||
it('calling display() twice correctly replaces file actions', function() {
|
||||
var $tr = FileList.addFile('testName.txt', 1234, new Date(), false, false, {download_url: 'test/download/url'});
|
||||
var fileData = {
|
||||
id: 18,
|
||||
type: 'file',
|
||||
name: 'testName.txt',
|
||||
mimetype: 'plain/text',
|
||||
size: '1234',
|
||||
etag: 'a01234c',
|
||||
mtime: '123456'
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
|
||||
FileActions.display($tr.find('td.filename'), true);
|
||||
FileActions.display($tr.find('td.filename'), true);
|
||||
|
@ -64,19 +77,36 @@ describe('FileActions tests', function() {
|
|||
});
|
||||
it('redirects to download URL when clicking download', function() {
|
||||
var redirectStub = sinon.stub(OC, 'redirect');
|
||||
// note: download_url is actually the link target, not the actual download URL...
|
||||
var $tr = FileList.addFile('test download File.txt', 1234, new Date(), false, false, {download_url: 'test/download/url'});
|
||||
var fileData = {
|
||||
id: 18,
|
||||
type: 'file',
|
||||
name: 'testName.txt',
|
||||
mimetype: 'plain/text',
|
||||
size: '1234',
|
||||
etag: 'a01234c',
|
||||
mtime: '123456'
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
FileActions.display($tr.find('td.filename'), true);
|
||||
|
||||
$tr.find('.action-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=test%20download%20File.txt');
|
||||
expect(redirectStub.getCall(0).args[0]).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=testName.txt');
|
||||
redirectStub.restore();
|
||||
});
|
||||
it('deletes file when clicking delete', function() {
|
||||
var deleteStub = sinon.stub(FileList, 'do_delete');
|
||||
var $tr = FileList.addFile('test delete File.txt', 1234, new Date());
|
||||
var fileData = {
|
||||
id: 18,
|
||||
type: 'file',
|
||||
name: 'testName.txt',
|
||||
mimetype: 'plain/text',
|
||||
size: '1234',
|
||||
etag: 'a01234c',
|
||||
mtime: '123456'
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
FileActions.display($tr.find('td.filename'), true);
|
||||
|
||||
$tr.find('.action.delete').click();
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
/* global OC, FileList */
|
||||
describe('FileList tests', function() {
|
||||
var testFiles, alertStub, notificationStub,
|
||||
pushStateStub;
|
||||
|
||||
beforeEach(function() {
|
||||
// init horrible parameters
|
||||
var $body = $('body');
|
||||
|
@ -28,45 +31,784 @@ describe('FileList tests', function() {
|
|||
$body.append('<input type="hidden" id="permissions" value="31"></input>');
|
||||
// dummy files table
|
||||
$body.append('<table id="filestable"></table>');
|
||||
|
||||
// prevents URL changes during tests
|
||||
pushStateStub = sinon.stub(window.history, 'pushState');
|
||||
|
||||
alertStub = sinon.stub(OC.dialogs, 'alert');
|
||||
notificationStub = sinon.stub(OC.Notification, 'show');
|
||||
|
||||
// init parameters and test table elements
|
||||
$('#testArea').append(
|
||||
'<input type="hidden" id="dir" value="/subdir"></input>' +
|
||||
'<input type="hidden" id="permissions" value="31"></input>' +
|
||||
// dummy controls
|
||||
'<div id="controls">' +
|
||||
' <div class="actions creatable"></div>' +
|
||||
' <div class="notCreatable"></div>' +
|
||||
'</div>' +
|
||||
// dummy table
|
||||
'<table id="filestable">' +
|
||||
'<thead><tr><th class="hidden">Name</th></tr></thead>' +
|
||||
'<tbody id="fileList"></tbody>' +
|
||||
'</table>' +
|
||||
'<div id="emptycontent">Empty content message</div>'
|
||||
);
|
||||
|
||||
testFiles = [{
|
||||
id: 1,
|
||||
type: 'file',
|
||||
name: 'One.txt',
|
||||
mimetype: 'text/plain',
|
||||
size: 12
|
||||
}, {
|
||||
id: 2,
|
||||
type: 'file',
|
||||
name: 'Two.jpg',
|
||||
mimetype: 'image/jpeg',
|
||||
size: 12049
|
||||
}, {
|
||||
id: 3,
|
||||
type: 'file',
|
||||
name: 'Three.pdf',
|
||||
mimetype: 'application/pdf',
|
||||
size: 58009
|
||||
}, {
|
||||
id: 4,
|
||||
type: 'dir',
|
||||
name: 'somedir',
|
||||
mimetype: 'httpd/unix-directory',
|
||||
size: 250
|
||||
}];
|
||||
|
||||
FileList.initialize();
|
||||
});
|
||||
afterEach(function() {
|
||||
testFiles = undefined;
|
||||
FileList.initialized = false;
|
||||
FileList.isEmpty = true;
|
||||
delete FileList._reloadCall;
|
||||
|
||||
$('#dir, #permissions, #filestable').remove();
|
||||
notificationStub.restore();
|
||||
alertStub.restore();
|
||||
pushStateStub.restore();
|
||||
});
|
||||
it('generates file element with correct attributes when calling addFile', function() {
|
||||
var lastMod = new Date(10000);
|
||||
// note: download_url is actually the link target, not the actual download URL...
|
||||
var $tr = FileList.addFile('testName.txt', 1234, lastMod, false, false, {download_url: 'test/download/url'});
|
||||
|
||||
expect($tr).toBeDefined();
|
||||
expect($tr[0].tagName.toLowerCase()).toEqual('tr');
|
||||
expect($tr.find('a:first').attr('href')).toEqual('test/download/url');
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('testName.txt');
|
||||
expect($tr.attr('data-size')).toEqual('1234');
|
||||
expect($tr.attr('data-permissions')).toEqual('31');
|
||||
//expect($tr.attr('data-mime')).toEqual('plain/text');
|
||||
describe('Getters', function() {
|
||||
it('Returns the current directory', function() {
|
||||
$('#dir').val('/one/two/three');
|
||||
expect(FileList.getCurrentDirectory()).toEqual('/one/two/three');
|
||||
});
|
||||
it('Returns the directory permissions as int', function() {
|
||||
$('#permissions').val('23');
|
||||
expect(FileList.getDirectoryPermissions()).toEqual(23);
|
||||
});
|
||||
});
|
||||
it('generates dir element with correct attributes when calling addDir', function() {
|
||||
var lastMod = new Date(10000);
|
||||
var $tr = FileList.addDir('testFolder', 1234, lastMod, false);
|
||||
describe('Adding files', function() {
|
||||
var clock, now;
|
||||
beforeEach(function() {
|
||||
// to prevent date comparison issues
|
||||
clock = sinon.useFakeTimers();
|
||||
now = new Date();
|
||||
});
|
||||
afterEach(function() {
|
||||
clock.restore();
|
||||
});
|
||||
it('generates file element with correct attributes when calling add() with file data', function() {
|
||||
var fileData = {
|
||||
id: 18,
|
||||
type: 'file',
|
||||
name: 'testName.txt',
|
||||
mimetype: 'plain/text',
|
||||
size: '1234',
|
||||
etag: 'a01234c',
|
||||
mtime: '123456'
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
|
||||
expect($tr).toBeDefined();
|
||||
expect($tr[0].tagName.toLowerCase()).toEqual('tr');
|
||||
expect($tr.attr('data-type')).toEqual('dir');
|
||||
expect($tr.attr('data-file')).toEqual('testFolder');
|
||||
expect($tr.attr('data-size')).toEqual('1234');
|
||||
expect($tr.attr('data-permissions')).toEqual('31');
|
||||
//expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
|
||||
expect($tr).toBeDefined();
|
||||
expect($tr[0].tagName.toLowerCase()).toEqual('tr');
|
||||
expect($tr.attr('data-id')).toEqual('18');
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('testName.txt');
|
||||
expect($tr.attr('data-size')).toEqual('1234');
|
||||
expect($tr.attr('data-etag')).toEqual('a01234c');
|
||||
expect($tr.attr('data-permissions')).toEqual('31');
|
||||
expect($tr.attr('data-mime')).toEqual('plain/text');
|
||||
expect($tr.attr('data-mtime')).toEqual('123456');
|
||||
expect($tr.find('a.name').attr('href')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=testName.txt');
|
||||
|
||||
expect($tr.find('.filesize').text()).toEqual('1 kB');
|
||||
expect(FileList.findFileEl('testName.txt')[0]).toEqual($tr[0]);
|
||||
});
|
||||
it('generates dir element with correct attributes when calling add() with dir data', function() {
|
||||
var fileData = {
|
||||
id: 19,
|
||||
type: 'dir',
|
||||
name: 'testFolder',
|
||||
mimetype: 'httpd/unix-directory',
|
||||
size: '1234',
|
||||
etag: 'a01234c',
|
||||
mtime: '123456'
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
|
||||
expect($tr).toBeDefined();
|
||||
expect($tr[0].tagName.toLowerCase()).toEqual('tr');
|
||||
expect($tr.attr('data-id')).toEqual('19');
|
||||
expect($tr.attr('data-type')).toEqual('dir');
|
||||
expect($tr.attr('data-file')).toEqual('testFolder');
|
||||
expect($tr.attr('data-size')).toEqual('1234');
|
||||
expect($tr.attr('data-etag')).toEqual('a01234c');
|
||||
expect($tr.attr('data-permissions')).toEqual('31');
|
||||
expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
|
||||
expect($tr.attr('data-mtime')).toEqual('123456');
|
||||
|
||||
expect($tr.find('.filesize').text()).toEqual('1 kB');
|
||||
|
||||
expect(FileList.findFileEl('testFolder')[0]).toEqual($tr[0]);
|
||||
});
|
||||
it('generates file element with default attributes when calling add() with minimal data', function() {
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'testFile.txt'
|
||||
};
|
||||
|
||||
clock.tick(123456);
|
||||
var $tr = FileList.add(fileData);
|
||||
|
||||
expect($tr).toBeDefined();
|
||||
expect($tr[0].tagName.toLowerCase()).toEqual('tr');
|
||||
expect($tr.attr('data-id')).toEqual(null);
|
||||
expect($tr.attr('data-type')).toEqual('file');
|
||||
expect($tr.attr('data-file')).toEqual('testFile.txt');
|
||||
expect($tr.attr('data-size')).toEqual(null);
|
||||
expect($tr.attr('data-etag')).toEqual(null);
|
||||
expect($tr.attr('data-permissions')).toEqual('31');
|
||||
expect($tr.attr('data-mime')).toEqual(null);
|
||||
expect($tr.attr('data-mtime')).toEqual('123456');
|
||||
|
||||
expect($tr.find('.filesize').text()).toEqual('Pending');
|
||||
});
|
||||
it('generates dir element with default attributes when calling add() with minimal data', function() {
|
||||
var fileData = {
|
||||
type: 'dir',
|
||||
name: 'testFolder'
|
||||
};
|
||||
clock.tick(123456);
|
||||
var $tr = FileList.add(fileData);
|
||||
|
||||
expect($tr).toBeDefined();
|
||||
expect($tr[0].tagName.toLowerCase()).toEqual('tr');
|
||||
expect($tr.attr('data-id')).toEqual(null);
|
||||
expect($tr.attr('data-type')).toEqual('dir');
|
||||
expect($tr.attr('data-file')).toEqual('testFolder');
|
||||
expect($tr.attr('data-size')).toEqual(null);
|
||||
expect($tr.attr('data-etag')).toEqual(null);
|
||||
expect($tr.attr('data-permissions')).toEqual('31');
|
||||
expect($tr.attr('data-mime')).toEqual('httpd/unix-directory');
|
||||
expect($tr.attr('data-mtime')).toEqual('123456');
|
||||
|
||||
expect($tr.find('.filesize').text()).toEqual('Pending');
|
||||
});
|
||||
it('generates file element with zero size when size is explicitly zero', function() {
|
||||
var fileData = {
|
||||
type: 'dir',
|
||||
name: 'testFolder',
|
||||
size: '0'
|
||||
};
|
||||
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() {
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'P comes after O.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() {
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'P comes after O.txt'
|
||||
};
|
||||
FileList.setFiles(testFiles);
|
||||
$tr = FileList.add(fileData, {insert: true});
|
||||
// after "One.txt"
|
||||
expect($tr.index()).toEqual(1);
|
||||
});
|
||||
it('removes empty content message and shows summary when adding first file', function() {
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'first file.txt',
|
||||
size: 12
|
||||
};
|
||||
FileList.setFiles([]);
|
||||
expect(FileList.isEmpty).toEqual(true);
|
||||
FileList.add(fileData);
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(1);
|
||||
// yes, ugly...
|
||||
expect($summary.find('.info').text()).toEqual('0 folders and 1 file');
|
||||
expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(true);
|
||||
expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false);
|
||||
expect($summary.find('.filesize').text()).toEqual('12 B');
|
||||
expect($('#filestable thead th').hasClass('hidden')).toEqual(false);
|
||||
expect($('#emptycontent').hasClass('hidden')).toEqual(true);
|
||||
expect(FileList.isEmpty).toEqual(false);
|
||||
});
|
||||
});
|
||||
describe('Removing files from the list', function() {
|
||||
it('Removes file from list when calling remove() and updates summary', function() {
|
||||
var $removedEl;
|
||||
FileList.setFiles(testFiles);
|
||||
$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.findFileEl('One.txt').length).toEqual(0);
|
||||
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(1);
|
||||
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);
|
||||
expect($summary.find('.filesize').text()).toEqual('69 kB');
|
||||
expect(FileList.isEmpty).toEqual(false);
|
||||
});
|
||||
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.findFileEl('One.txt').length).toEqual(0);
|
||||
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(0);
|
||||
expect($('#filestable thead th').hasClass('hidden')).toEqual(true);
|
||||
expect($('#emptycontent').hasClass('hidden')).toEqual(false);
|
||||
expect(FileList.isEmpty).toEqual(true);
|
||||
});
|
||||
});
|
||||
describe('Deleting files', function() {
|
||||
function doDelete() {
|
||||
var request, query;
|
||||
// note: normally called from FileActions
|
||||
FileList.do_delete(['One.txt', 'Two.jpg']);
|
||||
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
request = fakeServer.requests[0];
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/delete.php');
|
||||
|
||||
query = fakeServer.requests[0].requestBody;
|
||||
expect(OC.parseQueryString(query)).toEqual({'dir': '/subdir', files: '["One.txt","Two.jpg"]'});
|
||||
}
|
||||
it('calls delete.php, removes the deleted entries and updates summary', function() {
|
||||
FileList.setFiles(testFiles);
|
||||
doDelete();
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify({status: 'success'})
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(1);
|
||||
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);
|
||||
expect($summary.find('.filesize').text()).toEqual('57 kB');
|
||||
expect(FileList.isEmpty).toEqual(false);
|
||||
expect($('#filestable thead th').hasClass('hidden')).toEqual(false);
|
||||
expect($('#emptycontent').hasClass('hidden')).toEqual(true);
|
||||
|
||||
expect(notificationStub.notCalled).toEqual(true);
|
||||
});
|
||||
it('updates summary when deleting last file', function() {
|
||||
FileList.setFiles([testFiles[0], testFiles[1]]);
|
||||
doDelete();
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify({status: 'success'})
|
||||
);
|
||||
|
||||
expect(FileList.$fileList.find('tr:not(.summary)').length).toEqual(0);
|
||||
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(0);
|
||||
expect(FileList.isEmpty).toEqual(true);
|
||||
expect($('#filestable thead th').hasClass('hidden')).toEqual(true);
|
||||
expect($('#emptycontent').hasClass('hidden')).toEqual(false);
|
||||
});
|
||||
it('bring back deleted item when delete call failed', function() {
|
||||
FileList.setFiles(testFiles);
|
||||
doDelete();
|
||||
|
||||
fakeServer.requests[0].respond(
|
||||
200,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
JSON.stringify({status: 'error', data: {message: 'WOOT'}})
|
||||
);
|
||||
|
||||
// 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(notificationStub.calledOnce).toEqual(true);
|
||||
});
|
||||
});
|
||||
describe('Renaming files', function() {
|
||||
function doRename() {
|
||||
var $input, request;
|
||||
|
||||
FileList.setFiles(testFiles);
|
||||
|
||||
// trigger rename prompt
|
||||
FileList.rename('One.txt');
|
||||
$input = FileList.$fileList.find('input.filename');
|
||||
$input.val('One_renamed.txt').blur();
|
||||
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
var 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'});
|
||||
|
||||
// element is renamed before the request finishes
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
expect(FileList.findFileEl('One_renamed.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() {
|
||||
doRename();
|
||||
|
||||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'success',
|
||||
data: {
|
||||
name: 'One_renamed.txt'
|
||||
}
|
||||
}));
|
||||
|
||||
// element stays renamed
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(0);
|
||||
expect(FileList.findFileEl('One_renamed.txt').length).toEqual(1);
|
||||
|
||||
expect(alertStub.notCalled).toEqual(true);
|
||||
});
|
||||
it('Reverts file entry if rename ajax call failed', function() {
|
||||
doRename();
|
||||
|
||||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'error',
|
||||
data: {
|
||||
message: 'Something went wrong'
|
||||
}
|
||||
}));
|
||||
|
||||
// element was reverted
|
||||
expect(FileList.findFileEl('One.txt').length).toEqual(1);
|
||||
expect(FileList.findFileEl('One_renamed.txt').length).toEqual(0);
|
||||
|
||||
expect(alertStub.calledOnce).toEqual(true);
|
||||
});
|
||||
it('Correctly updates file link after rename', function() {
|
||||
var $tr;
|
||||
doRename();
|
||||
|
||||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'success',
|
||||
data: {
|
||||
name: 'One_renamed.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');
|
||||
});
|
||||
// FIXME: fix this in the source code!
|
||||
xit('Correctly updates file link after rename when path has same name', function() {
|
||||
var $tr;
|
||||
// evil case: because of buggy code
|
||||
$('#dir').val('/One.txt/subdir');
|
||||
doRename();
|
||||
|
||||
fakeServer.requests[0].respond(200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
status: 'success',
|
||||
data: {
|
||||
name: 'One_renamed.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.txt');
|
||||
});
|
||||
});
|
||||
describe('List rendering', function() {
|
||||
it('renders a list of files using add()', function() {
|
||||
var addSpy = sinon.spy(FileList, 'add');
|
||||
FileList.setFiles(testFiles);
|
||||
expect(addSpy.callCount).toEqual(4);
|
||||
expect($('#fileList tr:not(.summary)').length).toEqual(4);
|
||||
addSpy.restore();
|
||||
});
|
||||
it('updates summary using the file sizes', function() {
|
||||
var $summary;
|
||||
FileList.setFiles(testFiles);
|
||||
$summary = $('#fileList .summary');
|
||||
expect($summary.length).toEqual(1);
|
||||
expect($summary.find('.info').text()).toEqual('1 folder and 3 files');
|
||||
expect($summary.find('.filesize').text()).toEqual('69 kB');
|
||||
});
|
||||
it('shows headers, summary and hide empty content message after setting files', 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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
it('calling findFileEl() can find existing file element', function() {
|
||||
FileList.setFiles(testFiles);
|
||||
expect(FileList.findFileEl('Two.jpg').length).toEqual(1);
|
||||
});
|
||||
it('calling findFileEl() returns empty when file not found in file', function() {
|
||||
FileList.setFiles(testFiles);
|
||||
expect(FileList.findFileEl('unexist.dat').length).toEqual(0);
|
||||
});
|
||||
it('only add file if in same current directory', function() {
|
||||
$('#dir').val('/current dir');
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'testFile.txt',
|
||||
directory: '/current dir'
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
expect(FileList.findFileEl('testFile.txt').length).toEqual(1);
|
||||
});
|
||||
it('triggers "fileActionsReady" event after update', function() {
|
||||
var handler = sinon.stub();
|
||||
FileList.$fileList.on('fileActionsReady', handler);
|
||||
FileList.setFiles(testFiles);
|
||||
expect(handler.calledOnce).toEqual(true);
|
||||
});
|
||||
it('triggers "updated" event after update', function() {
|
||||
var handler = sinon.stub();
|
||||
FileList.$fileList.on('updated', handler);
|
||||
FileList.setFiles(testFiles);
|
||||
expect(handler.calledOnce).toEqual(true);
|
||||
});
|
||||
});
|
||||
describe('file previews', function() {
|
||||
var previewLoadStub;
|
||||
|
||||
function getImageUrl($el) {
|
||||
// might be slightly different cross-browser
|
||||
var url = $el.css('background-image');
|
||||
var r = url.match(/url\(['"]?([^'")]*)['"]?\)/);
|
||||
if (!r) {
|
||||
return url;
|
||||
}
|
||||
return r[1];
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
previewLoadStub = sinon.stub(Files, 'lazyLoadPreview');
|
||||
});
|
||||
afterEach(function() {
|
||||
previewLoadStub.restore();
|
||||
});
|
||||
it('renders default icon for file when none provided and no preview is available', function() {
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'testFile.txt'
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
var $td = $tr.find('td.filename');
|
||||
expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/file.svg');
|
||||
expect(previewLoadStub.notCalled).toEqual(true);
|
||||
});
|
||||
it('renders default icon for dir when none provided and no preview is available', function() {
|
||||
var fileData = {
|
||||
type: 'dir',
|
||||
name: 'test dir'
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
var $td = $tr.find('td.filename');
|
||||
expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/folder.svg');
|
||||
expect(previewLoadStub.notCalled).toEqual(true);
|
||||
});
|
||||
it('renders provided icon for file when provided', function() {
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'test dir',
|
||||
icon: OC.webroot + '/core/img/filetypes/application-pdf.svg'
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
var $td = $tr.find('td.filename');
|
||||
expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/application-pdf.svg');
|
||||
expect(previewLoadStub.notCalled).toEqual(true);
|
||||
});
|
||||
it('renders preview when no icon was provided and preview is available', function() {
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'test dir',
|
||||
isPreviewAvailable: true
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
var $td = $tr.find('td.filename');
|
||||
expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/file.svg');
|
||||
expect(previewLoadStub.calledOnce).toEqual(true);
|
||||
// third argument is callback
|
||||
previewLoadStub.getCall(0).args[2](OC.webroot + '/somepath.png');
|
||||
expect(getImageUrl($td)).toEqual(OC.webroot + '/somepath.png');
|
||||
});
|
||||
it('renders default file type icon when no icon was provided and no preview is available', function() {
|
||||
var fileData = {
|
||||
type: 'file',
|
||||
name: 'test dir',
|
||||
isPreviewAvailable: false
|
||||
};
|
||||
var $tr = FileList.add(fileData);
|
||||
var $td = $tr.find('td.filename');
|
||||
expect(getImageUrl($td)).toEqual(OC.webroot + '/core/img/filetypes/file.svg');
|
||||
expect(previewLoadStub.notCalled).toEqual(true);
|
||||
});
|
||||
});
|
||||
describe('viewer mode', function() {
|
||||
it('enabling viewer mode hides files table and action buttons', function() {
|
||||
FileList.setViewerMode(true);
|
||||
expect($('#filestable').hasClass('hidden')).toEqual(true);
|
||||
expect($('.actions').hasClass('hidden')).toEqual(true);
|
||||
expect($('.notCreatable').hasClass('hidden')).toEqual(true);
|
||||
});
|
||||
it('disabling viewer mode restores files table and action buttons', function() {
|
||||
FileList.setViewerMode(true);
|
||||
FileList.setViewerMode(false);
|
||||
expect($('#filestable').hasClass('hidden')).toEqual(false);
|
||||
expect($('.actions').hasClass('hidden')).toEqual(false);
|
||||
expect($('.notCreatable').hasClass('hidden')).toEqual(true);
|
||||
});
|
||||
it('disabling viewer mode restores files table and action buttons with correct permissions', function() {
|
||||
$('#permissions').val(0);
|
||||
FileList.setViewerMode(true);
|
||||
FileList.setViewerMode(false);
|
||||
expect($('#filestable').hasClass('hidden')).toEqual(false);
|
||||
expect($('.actions').hasClass('hidden')).toEqual(true);
|
||||
expect($('.notCreatable').hasClass('hidden')).toEqual(false);
|
||||
});
|
||||
});
|
||||
describe('loading file list', function() {
|
||||
beforeEach(function() {
|
||||
var data = {
|
||||
status: 'success',
|
||||
data: {
|
||||
files: testFiles,
|
||||
permissions: 31
|
||||
}
|
||||
};
|
||||
fakeServer.respondWith(/\/index\.php\/apps\/files\/ajax\/list.php\?dir=%2F(subdir|anothersubdir)/, [
|
||||
200, {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
JSON.stringify(data)
|
||||
]);
|
||||
});
|
||||
it('fetches file list from server and renders it when reload() is called', function() {
|
||||
FileList.reload();
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
var url = fakeServer.requests[0].url;
|
||||
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.findFileEl('One.txt').length).toEqual(1);
|
||||
});
|
||||
it('switches dir and fetches file list when calling changeDirectory()', function() {
|
||||
FileList.changeDirectory('/anothersubdir');
|
||||
expect(FileList.getCurrentDirectory()).toEqual('/anothersubdir');
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
var url = fakeServer.requests[0].url;
|
||||
var query = url.substr(url.indexOf('?') + 1);
|
||||
expect(OC.parseQueryString(query)).toEqual({'dir': '/anothersubdir'});
|
||||
fakeServer.respond();
|
||||
});
|
||||
it('switches to root dir when current directory does not exist', function() {
|
||||
fakeServer.respondWith(/\/index\.php\/apps\/files\/ajax\/list.php\?dir=%2funexist/, [
|
||||
404, {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
''
|
||||
]);
|
||||
FileList.changeDirectory('/unexist');
|
||||
fakeServer.respond();
|
||||
expect(FileList.getCurrentDirectory()).toEqual('/');
|
||||
});
|
||||
it('shows mask before loading file list then hides it at the end', function() {
|
||||
var showMaskStub = sinon.stub(FileList, 'showMask');
|
||||
var hideMaskStub = sinon.stub(FileList, 'hideMask');
|
||||
FileList.changeDirectory('/anothersubdir');
|
||||
expect(showMaskStub.calledOnce).toEqual(true);
|
||||
expect(hideMaskStub.calledOnce).toEqual(false);
|
||||
fakeServer.respond();
|
||||
expect(showMaskStub.calledOnce).toEqual(true);
|
||||
expect(hideMaskStub.calledOnce).toEqual(true);
|
||||
showMaskStub.restore();
|
||||
hideMaskStub.restore();
|
||||
});
|
||||
it('changes URL to target dir', function() {
|
||||
FileList.changeDirectory('/somedir');
|
||||
expect(pushStateStub.calledOnce).toEqual(true);
|
||||
expect(pushStateStub.getCall(0).args[0]).toEqual({dir: '/somedir'});
|
||||
expect(pushStateStub.getCall(0).args[2]).toEqual(OC.webroot + '/index.php/apps/files?dir=/somedir');
|
||||
});
|
||||
it('refreshes breadcrumb after update', function() {
|
||||
var setDirSpy = sinon.spy(FileList.breadcrumb, 'setDirectory');
|
||||
FileList.changeDirectory('/anothersubdir');
|
||||
fakeServer.respond();
|
||||
expect(FileList.breadcrumb.setDirectory.calledOnce).toEqual(true);
|
||||
expect(FileList.breadcrumb.setDirectory.calledWith('/anothersubdir')).toEqual(true);
|
||||
setDirSpy.restore();
|
||||
});
|
||||
});
|
||||
describe('breadcrumb events', function() {
|
||||
beforeEach(function() {
|
||||
var data = {
|
||||
status: 'success',
|
||||
data: {
|
||||
files: testFiles,
|
||||
permissions: 31
|
||||
}
|
||||
};
|
||||
fakeServer.respondWith(/\/index\.php\/apps\/files\/ajax\/list.php\?dir=%2Fsubdir/, [
|
||||
200, {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
JSON.stringify(data)
|
||||
]);
|
||||
});
|
||||
it('clicking on root breadcrumb changes directory to root', function() {
|
||||
FileList.changeDirectory('/subdir/two/three with space/four/five');
|
||||
fakeServer.respond();
|
||||
var changeDirStub = sinon.stub(FileList, 'changeDirectory');
|
||||
FileList.breadcrumb.$el.find('.crumb:eq(0)').click();
|
||||
|
||||
expect(changeDirStub.calledOnce).toEqual(true);
|
||||
expect(changeDirStub.getCall(0).args[0]).toEqual('/');
|
||||
changeDirStub.restore();
|
||||
});
|
||||
it('clicking on breadcrumb changes directory', function() {
|
||||
FileList.changeDirectory('/subdir/two/three with space/four/five');
|
||||
fakeServer.respond();
|
||||
var changeDirStub = sinon.stub(FileList, 'changeDirectory');
|
||||
FileList.breadcrumb.$el.find('.crumb:eq(3)').click();
|
||||
|
||||
expect(changeDirStub.calledOnce).toEqual(true);
|
||||
expect(changeDirStub.getCall(0).args[0]).toEqual('/subdir/two/three with space');
|
||||
changeDirStub.restore();
|
||||
});
|
||||
it('dropping files on breadcrumb calls move operation', function() {
|
||||
var request, query, testDir = '/subdir/two/three with space/four/five';
|
||||
FileList.changeDirectory(testDir);
|
||||
fakeServer.respond();
|
||||
var $crumb = FileList.breadcrumb.$el.find('.crumb:eq(3)');
|
||||
// no idea what this is but is required by the handler
|
||||
var ui = {
|
||||
helper: {
|
||||
find: sinon.stub()
|
||||
}
|
||||
};
|
||||
// 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>')
|
||||
]);
|
||||
// simulate drop event
|
||||
FileList._onDropOnBreadCrumb.call($crumb, new $.Event('drop'), ui);
|
||||
|
||||
// will trigger two calls to move.php (first one was previous list.php)
|
||||
expect(fakeServer.requests.length).toEqual(3);
|
||||
|
||||
request = fakeServer.requests[1];
|
||||
expect(request.method).toEqual('POST');
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/move.php');
|
||||
query = OC.parseQueryString(request.requestBody);
|
||||
expect(query).toEqual({
|
||||
target: '/subdir/two/three with space',
|
||||
dir: testDir,
|
||||
file: 'One.txt'
|
||||
});
|
||||
|
||||
request = fakeServer.requests[2];
|
||||
expect(request.method).toEqual('POST');
|
||||
expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/move.php');
|
||||
query = OC.parseQueryString(request.requestBody);
|
||||
expect(query).toEqual({
|
||||
target: '/subdir/two/three with space',
|
||||
dir: testDir,
|
||||
file: 'Two.jpg'
|
||||
});
|
||||
});
|
||||
it('dropping files on same dir breadcrumb does nothing', function() {
|
||||
var request, query, testDir = '/subdir/two/three with space/four/five';
|
||||
FileList.changeDirectory(testDir);
|
||||
fakeServer.respond();
|
||||
var $crumb = FileList.breadcrumb.$el.find('.crumb:last');
|
||||
// no idea what this is but is required by the handler
|
||||
var ui = {
|
||||
helper: {
|
||||
find: sinon.stub()
|
||||
}
|
||||
};
|
||||
// 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>')
|
||||
]);
|
||||
// simulate drop event
|
||||
FileList._onDropOnBreadCrumb.call($crumb, new $.Event('drop'), ui);
|
||||
|
||||
// no extra server request
|
||||
expect(fakeServer.requests.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
describe('Download Url', function() {
|
||||
it('returns correct download URL for single files', function() {
|
||||
expect(FileList.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=some%20file.txt');
|
||||
expect(FileList.getDownloadUrl('some file.txt', '/anotherpath/abc')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fanotherpath%2Fabc&files=some%20file.txt');
|
||||
expect(Files.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=some%20file.txt');
|
||||
expect(Files.getDownloadUrl('some file.txt', '/anotherpath/abc')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fanotherpath%2Fabc&files=some%20file.txt');
|
||||
$('#dir').val('/');
|
||||
expect(FileList.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=some%20file.txt');
|
||||
expect(Files.getDownloadUrl('some file.txt')).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2F&files=some%20file.txt');
|
||||
});
|
||||
it('returns correct download URL for multiple files', function() {
|
||||
expect(FileList.getDownloadUrl(['a b c.txt', 'd e f.txt'])).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22a%20b%20c.txt%22%2C%22d%20e%20f.txt%22%5D');
|
||||
expect(Files.getDownloadUrl(['a b c.txt', 'd e f.txt'])).toEqual(OC.webroot + '/index.php/apps/files/ajax/download.php?dir=%2Fsubdir&files=%5B%22a%20b%20c.txt%22%2C%22d%20e%20f.txt%22%5D');
|
||||
});
|
||||
it('returns the correct ajax URL', 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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// only need filesystem apps
|
||||
$RUNTIME_APPTYPES=array('filesystem');
|
||||
|
||||
// Init owncloud
|
||||
|
||||
if(!\OC_App::isEnabled('files_sharing')){
|
||||
exit;
|
||||
}
|
||||
|
||||
if(!isset($_GET['t'])){
|
||||
\OC_Response::setStatus(400); //400 Bad Request
|
||||
\OC_Log::write('core-preview', 'No token parameter was passed', \OC_Log::DEBUG);
|
||||
exit;
|
||||
}
|
||||
|
||||
$token = $_GET['t'];
|
||||
|
||||
$password = null;
|
||||
if (isset($_POST['password'])) {
|
||||
$password = $_POST['password'];
|
||||
}
|
||||
|
||||
$relativePath = null;
|
||||
if (isset($_GET['dir'])) {
|
||||
$relativePath = $_GET['dir'];
|
||||
}
|
||||
|
||||
$data = \OCA\Files_Sharing\Helper::setupFromToken($token, $relativePath, $password);
|
||||
|
||||
$linkItem = $data['linkItem'];
|
||||
// Load the files
|
||||
$dir = $data['realPath'];
|
||||
|
||||
$dir = \OC\Files\Filesystem::normalizePath($dir);
|
||||
if (!\OC\Files\Filesystem::is_dir($dir . '/')) {
|
||||
\OC_Response::setStatus(404);
|
||||
\OCP\JSON::error(array('success' => false));
|
||||
exit();
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$baseUrl = OCP\Util::linkTo('files_sharing', 'index.php') . '?t=' . urlencode($token) . '&dir=';
|
||||
|
||||
// make filelist
|
||||
$files = \OCA\Files\Helper::getFiles($dir);
|
||||
|
||||
$formattedFiles = array();
|
||||
foreach ($files as $file) {
|
||||
$entry = \OCA\Files\Helper::formatFileInfo($file);
|
||||
unset($entry['directory']); // for now
|
||||
$entry['permissions'] = \OCP\PERMISSION_READ;
|
||||
$formattedFiles[] = $entry;
|
||||
}
|
||||
|
||||
$data['directory'] = $relativePath;
|
||||
$data['files'] = $formattedFiles;
|
||||
$data['dirToken'] = $linkItem['token'];
|
||||
|
||||
$permissions = $linkItem['permissions'];
|
||||
|
||||
// if globally disabled
|
||||
if (OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') {
|
||||
// only allow reading
|
||||
$permissions = \OCP\PERMISSION_READ;
|
||||
}
|
||||
|
||||
$data['permissions'] = $permissions;
|
||||
|
||||
OCP\JSON::success(array('data' => $data));
|
|
@ -35,6 +35,11 @@ body {
|
|||
background: #fff;
|
||||
text-align: center;
|
||||
margin: 45px auto 0;
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
#preview .notCreatable {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#noPreview {
|
||||
|
|
|
@ -8,16 +8,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* global OC, FileList, FileActions */
|
||||
|
||||
// Override download path to files_sharing/public.php
|
||||
function fileDownloadPath(dir, file) {
|
||||
var url = $('#downloadURL').val();
|
||||
if (url.indexOf('&path=') != -1) {
|
||||
url += '/'+file;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
/* global OC, FileActions, FileList, Files */
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
|
@ -31,32 +22,44 @@ $(document).ready(function() {
|
|||
action($('#filename').val());
|
||||
}
|
||||
}
|
||||
FileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function(filename) {
|
||||
var tr = FileList.findFileEl(filename);
|
||||
if (tr.length > 0) {
|
||||
window.location = $(tr).find('a.name').attr('href');
|
||||
}
|
||||
});
|
||||
|
||||
// override since the format is different
|
||||
FileList.getDownloadUrl = function(filename, dir) {
|
||||
if ($.isArray(filename)) {
|
||||
filename = JSON.stringify(filename);
|
||||
}
|
||||
var path = dir || FileList.getCurrentDirectory();
|
||||
var params = {
|
||||
service: 'files',
|
||||
t: $('#sharingToken').val(),
|
||||
path: path,
|
||||
download: null
|
||||
};
|
||||
if (filename) {
|
||||
params.files = filename;
|
||||
}
|
||||
return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params);
|
||||
};
|
||||
}
|
||||
|
||||
// override since the format is different
|
||||
Files.getDownloadUrl = function(filename, dir) {
|
||||
if ($.isArray(filename)) {
|
||||
filename = JSON.stringify(filename);
|
||||
}
|
||||
var path = dir || FileList.getCurrentDirectory();
|
||||
var params = {
|
||||
service: 'files',
|
||||
t: $('#sharingToken').val(),
|
||||
path: path,
|
||||
files: filename,
|
||||
download: null
|
||||
};
|
||||
return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params);
|
||||
};
|
||||
|
||||
Files.getAjaxUrl = function(action, params) {
|
||||
params = params || {};
|
||||
params.t = $('#sharingToken').val();
|
||||
return OC.filePath('files_sharing', 'ajax', action + '.php') + '?' + OC.buildQueryString(params);
|
||||
};
|
||||
|
||||
FileList.linkTo = function(dir) {
|
||||
var params = {
|
||||
service: 'files',
|
||||
t: $('#sharingToken').val(),
|
||||
dir: dir
|
||||
};
|
||||
return OC.filePath('', '', 'public.php') + '?' + OC.buildQueryString(params);
|
||||
};
|
||||
|
||||
Files.generatePreviewUrl = function(urlSpec) {
|
||||
urlSpec.t = $('#dirToken').val();
|
||||
return OC.generateUrl('/apps/files_sharing/ajax/publicpreview.php?') + $.param(urlSpec);
|
||||
};
|
||||
|
||||
var file_upload_start = $('#file_upload_start');
|
||||
file_upload_start.on('fileuploadadd', function(e, data) {
|
||||
// Add custom data to the upload handler
|
||||
|
|
|
@ -1,15 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2014
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3
|
||||
* or later.
|
||||
*
|
||||
* See the COPYING-README file.
|
||||
*
|
||||
*/
|
||||
|
||||
/* global OC, t, FileList, FileActions */
|
||||
$(document).ready(function() {
|
||||
|
||||
var disableSharing = $('#disableSharing').data('status'),
|
||||
sharesLoaded = false;
|
||||
|
||||
if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !disableSharing) {
|
||||
var oldCreateRow = FileList._createRow;
|
||||
FileList._createRow = function(fileData) {
|
||||
var tr = oldCreateRow.apply(this, arguments);
|
||||
if (fileData.shareOwner) {
|
||||
tr.attr('data-share-owner', fileData.shareOwner);
|
||||
}
|
||||
return tr;
|
||||
};
|
||||
|
||||
$('#fileList').on('fileActionsReady',function(){
|
||||
|
||||
var allShared = $('#fileList').find('[data-share-owner]').find('[data-Action="Share"]');
|
||||
var allShared = $('#fileList').find('[data-share-owner] [data-Action="Share"]');
|
||||
allShared.addClass('permanent');
|
||||
allShared.find('span').text(function(){
|
||||
$owner = $(this).closest('tr').attr('data-share-owner');
|
||||
var $owner = $(this).closest('tr').attr('data-share-owner');
|
||||
return ' ' + t('files_sharing', 'Shared by {owner}', {owner: $owner});
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\Files_Sharing;
|
||||
|
||||
class Helper {
|
||||
|
||||
/**
|
||||
* Sets up the filesystem and user for public sharing
|
||||
* @param string $token string share token
|
||||
* @param string $relativePath optional path relative to the share
|
||||
* @param string $password optional password
|
||||
*/
|
||||
public static function setupFromToken($token, $relativePath = null, $password = null) {
|
||||
\OC_User::setIncognitoMode(true);
|
||||
|
||||
$linkItem = \OCP\Share::getShareByToken($token);
|
||||
if($linkItem === false || ($linkItem['item_type'] !== 'file' && $linkItem['item_type'] !== 'folder')) {
|
||||
\OC_Response::setStatus(404);
|
||||
\OC_Log::write('core-preview', 'Passed token parameter is not valid', \OC_Log::DEBUG);
|
||||
exit;
|
||||
}
|
||||
|
||||
if(!isset($linkItem['uid_owner']) || !isset($linkItem['file_source'])) {
|
||||
\OC_Response::setStatus(500);
|
||||
\OC_Log::write('core-preview', 'Passed token seems to be valid, but it does not contain all necessary information . ("' . $token . '")', \OC_Log::WARN);
|
||||
exit;
|
||||
}
|
||||
|
||||
$type = $linkItem['item_type'];
|
||||
$fileSource = $linkItem['file_source'];
|
||||
$shareOwner = $linkItem['uid_owner'];
|
||||
$rootLinkItem = \OCP\Share::resolveReShare($linkItem);
|
||||
$path = null;
|
||||
if (isset($rootLinkItem['uid_owner'])) {
|
||||
\OCP\JSON::checkUserExists($rootLinkItem['uid_owner']);
|
||||
\OC_Util::tearDownFS();
|
||||
\OC_Util::setupFS($rootLinkItem['uid_owner']);
|
||||
$path = \OC\Files\Filesystem::getPath($linkItem['file_source']);
|
||||
}
|
||||
|
||||
if ($path === null) {
|
||||
\OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG);
|
||||
\OC_Response::setStatus(404);
|
||||
\OCP\JSON::error(array('success' => false));
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!isset($linkItem['item_type'])) {
|
||||
\OCP\Util::writeLog('share', 'No item type set for share id: ' . $linkItem['id'], \OCP\Util::ERROR);
|
||||
\OC_Response::setStatus(404);
|
||||
\OCP\JSON::error(array('success' => false));
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($linkItem['share_with'])) {
|
||||
if (!self::authenticate($linkItem, $password)) {
|
||||
\OC_Response::setStatus(403);
|
||||
\OCP\JSON::error(array('success' => false));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
$basePath = $path;
|
||||
$rootName = basename($path);
|
||||
|
||||
if ($relativePath !== null && \OC\Files\Filesystem::isReadable($basePath . $relativePath)) {
|
||||
$path .= \OC\Files\Filesystem::normalizePath($relativePath);
|
||||
}
|
||||
|
||||
return array(
|
||||
'linkItem' => $linkItem,
|
||||
'basePath' => $basePath,
|
||||
'realPath' => $path
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate link item with the given password
|
||||
* or with the session if no password was given.
|
||||
* @param array $linkItem link item array
|
||||
* @param string $password optional password
|
||||
*
|
||||
* @return true if authorized, false otherwise
|
||||
*/
|
||||
public static function authenticate($linkItem, $password) {
|
||||
if ($password !== null) {
|
||||
if ($linkItem['share_type'] == \OCP\Share::SHARE_TYPE_LINK) {
|
||||
// Check Password
|
||||
$forcePortable = (CRYPT_BLOWFISH != 1);
|
||||
$hasher = new PasswordHash(8, $forcePortable);
|
||||
if (!($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''),
|
||||
$linkItem['share_with']))) {
|
||||
return false;
|
||||
} else {
|
||||
// Save item id in session for future requests
|
||||
\OC::$session->set('public_link_authenticated', $linkItem['id']);
|
||||
}
|
||||
} else {
|
||||
\OCP\Util::writeLog('share', 'Unknown share type '.$linkItem['share_type']
|
||||
.' for share id '.$linkItem['id'], \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// not authenticated ?
|
||||
if ( ! \OC::$session->exists('public_link_authenticated')
|
||||
|| \OC::$session->get('public_link_authenticated') !== $linkItem['id']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -11,31 +11,6 @@ if ($appConfig->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') {
|
|||
exit();
|
||||
}
|
||||
|
||||
function fileCmp($a, $b) {
|
||||
if ($a['type'] == 'dir' and $b['type'] != 'dir') {
|
||||
return -1;
|
||||
} elseif ($a['type'] != 'dir' and $b['type'] == 'dir') {
|
||||
return 1;
|
||||
} else {
|
||||
return strnatcasecmp($a['name'], $b['name']);
|
||||
}
|
||||
}
|
||||
|
||||
function determineIcon($file, $sharingRoot, $sharingToken) {
|
||||
// for folders we simply reuse the files logic
|
||||
if($file['type'] == 'dir') {
|
||||
return \OCA\Files\Helper::determineIcon($file);
|
||||
}
|
||||
|
||||
$relativePath = substr($file['path'], 6);
|
||||
$relativePath = substr($relativePath, strlen($sharingRoot));
|
||||
if($file['isPreviewAvailable']) {
|
||||
return OCP\publicPreview_icon($relativePath, $sharingToken) . '&c=' . $file['etag'];
|
||||
}
|
||||
$icon = OCP\mimetype_icon($file['mimetype']);
|
||||
return substr($icon, 0, -3) . 'svg';
|
||||
}
|
||||
|
||||
if (isset($_GET['t'])) {
|
||||
$token = $_GET['t'];
|
||||
$linkItem = OCP\Share::getShareByToken($token, false);
|
||||
|
@ -153,13 +128,6 @@ if (isset($path)) {
|
|||
$tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path));
|
||||
$tmpl->assign('dirToken', $linkItem['token']);
|
||||
$tmpl->assign('sharingToken', $token);
|
||||
$allowPublicUploadEnabled = (bool) ($linkItem['permissions'] & OCP\PERMISSION_CREATE);
|
||||
if ($appConfig->getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') {
|
||||
$allowPublicUploadEnabled = false;
|
||||
}
|
||||
if ($linkItem['item_type'] !== 'folder') {
|
||||
$allowPublicUploadEnabled = false;
|
||||
}
|
||||
|
||||
$urlLinkIdentifiers= (isset($token)?'&t='.$token:'')
|
||||
.(isset($_GET['dir'])?'&dir='.$_GET['dir']:'')
|
||||
|
@ -170,64 +138,18 @@ if (isset($path)) {
|
|||
|
||||
OCP\Util::addStyle('files', 'files');
|
||||
OCP\Util::addStyle('files', 'upload');
|
||||
OCP\Util::addScript('files', 'breadcrumb');
|
||||
OCP\Util::addScript('files', 'files');
|
||||
OCP\Util::addScript('files', 'filelist');
|
||||
OCP\Util::addscript('files', 'keyboardshortcuts');
|
||||
$files = array();
|
||||
$rootLength = strlen($basePath) + 1;
|
||||
$totalSize = 0;
|
||||
foreach (\OC\Files\Filesystem::getDirectoryContent($path) as $i) {
|
||||
$totalSize += $i['size'];
|
||||
$i['date'] = OCP\Util::formatDate($i['mtime']);
|
||||
if ($i['type'] == 'file') {
|
||||
$fileinfo = pathinfo($i['name']);
|
||||
$i['basename'] = $fileinfo['filename'];
|
||||
if (!empty($fileinfo['extension'])) {
|
||||
$i['extension'] = '.' . $fileinfo['extension'];
|
||||
} else {
|
||||
$i['extension'] = '';
|
||||
}
|
||||
}
|
||||
$i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($i['mimetype']);
|
||||
$i['directory'] = $getPath;
|
||||
$i['permissions'] = OCP\PERMISSION_READ;
|
||||
$i['icon'] = determineIcon($i, $basePath, $token);
|
||||
$files[] = $i;
|
||||
}
|
||||
usort($files, "fileCmp");
|
||||
|
||||
// Make breadcrumb
|
||||
$breadcrumb = array();
|
||||
$pathtohere = '';
|
||||
foreach (explode('/', $getPath) as $i) {
|
||||
if ($i != '') {
|
||||
$pathtohere .= '/' . $i;
|
||||
$breadcrumb[] = array('dir' => $pathtohere, 'name' => $i);
|
||||
}
|
||||
}
|
||||
$list = new OCP\Template('files', 'part.list', '');
|
||||
$list->assign('files', $files);
|
||||
$list->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path=');
|
||||
$list->assign('downloadURL',
|
||||
OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=');
|
||||
$list->assign('isPublic', true);
|
||||
$list->assign('sharingtoken', $token);
|
||||
$list->assign('sharingroot', $basePath);
|
||||
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '');
|
||||
$breadcrumbNav->assign('breadcrumb', $breadcrumb);
|
||||
$breadcrumbNav->assign('rootBreadCrumb', $rootName);
|
||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path=');
|
||||
$maxUploadFilesize=OCP\Util::maxUploadFilesize($path);
|
||||
$fileHeader = (!isset($files) or count($files) > 0);
|
||||
$emptyContent = ($allowPublicUploadEnabled and !$fileHeader);
|
||||
|
||||
$freeSpace=OCP\Util::freeSpace($path);
|
||||
$uploadLimit=OCP\Util::uploadLimit();
|
||||
$folder = new OCP\Template('files', 'index', '');
|
||||
$folder->assign('fileList', $list->fetchPage());
|
||||
$folder->assign('breadcrumb', $breadcrumbNav->fetchPage());
|
||||
$folder->assign('dir', $getPath);
|
||||
$folder->assign('isCreatable', $allowPublicUploadEnabled);
|
||||
$folder->assign('dirToken', $linkItem['token']);
|
||||
$folder->assign('permissions', OCP\PERMISSION_READ);
|
||||
$folder->assign('isPublic',true);
|
||||
|
@ -239,15 +161,11 @@ if (isset($path)) {
|
|||
$folder->assign('uploadLimit', $uploadLimit); // PHP upload limit
|
||||
$folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
|
||||
$folder->assign('usedSpacePercent', 0);
|
||||
$folder->assign('fileHeader', $fileHeader);
|
||||
$folder->assign('disableSharing', true);
|
||||
$folder->assign('trash', false);
|
||||
$folder->assign('emptyContent', $emptyContent);
|
||||
$folder->assign('ajaxLoad', false);
|
||||
$tmpl->assign('folder', $folder->fetchPage());
|
||||
$maxInputFileSize = OCP\Config::getSystemValue('maxZipInputSize', OCP\Util::computerFileSize('800 MB'));
|
||||
$allowZip = OCP\Config::getSystemValue('allowZipDownload', true)
|
||||
&& ( $maxInputFileSize === 0 || $totalSize <= $maxInputFileSize);
|
||||
$allowZip = OCP\Config::getSystemValue('allowZipDownload', true);
|
||||
$tmpl->assign('allowZipDownload', intval($allowZip));
|
||||
$tmpl->assign('downloadURL',
|
||||
OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=' . urlencode($getPath));
|
||||
|
|
|
@ -4,21 +4,8 @@ OCP\JSON::checkLoggedIn();
|
|||
|
||||
// Load the files
|
||||
$dir = isset( $_GET['dir'] ) ? $_GET['dir'] : '';
|
||||
$doBreadcrumb = isset( $_GET['breadcrumb'] ) ? true : false;
|
||||
$data = array();
|
||||
|
||||
// Make breadcrumb
|
||||
if($doBreadcrumb) {
|
||||
$breadcrumb = \OCA\Files_Trashbin\Helper::makeBreadcrumb($dir);
|
||||
|
||||
$breadcrumbNav = new OCP\Template('files_trashbin', 'part.breadcrumb', '');
|
||||
$breadcrumbNav->assign('breadcrumb', $breadcrumb, false);
|
||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php') . '?dir=');
|
||||
$breadcrumbNav->assign('home', OCP\Util::linkTo('files', 'index.php'));
|
||||
|
||||
$data['breadcrumb'] = $breadcrumbNav->fetchPage();
|
||||
}
|
||||
|
||||
// make filelist
|
||||
try {
|
||||
$files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir);
|
||||
|
@ -27,19 +14,11 @@ try {
|
|||
exit();
|
||||
}
|
||||
|
||||
$dirlisting = false;
|
||||
if ($dir && $dir !== '/') {
|
||||
$dirlisting = true;
|
||||
}
|
||||
|
||||
$encodedDir = \OCP\Util::encodePath($dir);
|
||||
$list = new OCP\Template('files_trashbin', 'part.list', '');
|
||||
$list->assign('files', $files, false);
|
||||
$list->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php'). '?dir='.$encodedDir);
|
||||
$list->assign('downloadURL', OCP\Util::linkToRoute('download', array('file' => '/')));
|
||||
$list->assign('dirlisting', $dirlisting);
|
||||
$list->assign('disableDownloadActions', true);
|
||||
$data['files'] = $list->fetchPage();
|
||||
|
||||
$data['permissions'] = 0;
|
||||
$data['directory'] = $dir;
|
||||
$data['files'] = \OCA\Files_Trashbin\Helper::formatFileInfos($files);
|
||||
|
||||
OCP\JSON::success(array('data' => $data));
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ try{
|
|||
if ($view->is_dir($file)) {
|
||||
$mimetype = 'httpd/unix-directory';
|
||||
} else {
|
||||
$pathInfo = pathinfo($file);
|
||||
$pathInfo = pathinfo(ltrim($file, '/'));
|
||||
$fileName = $pathInfo['basename'];
|
||||
// if in root dir
|
||||
if ($pathInfo['dirname'] === '.') {
|
||||
|
|
|
@ -19,7 +19,7 @@ if (isset($_POST['allfiles']) and $_POST['allfiles'] === 'true') {
|
|||
foreach (OCA\Files_Trashbin\Helper::getTrashFiles($dir) as $file) {
|
||||
$fileName = $file['name'];
|
||||
if (!$dirListing) {
|
||||
$fileName .= '.d' . $file['timestamp'];
|
||||
$fileName .= '.d' . $file['mtime'];
|
||||
}
|
||||
$list[] = $fileName;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#fileList td a.file, #fileList td a.file span {
|
||||
#fileList tr[data-type="file"] td a.name,
|
||||
#fileList tr[data-type="file"] td a.name span {
|
||||
cursor: default;
|
||||
}
|
||||
|
|
|
@ -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', 'breadcrumb');
|
||||
OCP\Util::addScript('files', 'filelist');
|
||||
// filelist overrides
|
||||
OCP\Util::addScript('files_trashbin', 'filelist');
|
||||
|
@ -34,48 +35,7 @@ if ($isIE8 && isset($_GET['dir'])){
|
|||
exit();
|
||||
}
|
||||
|
||||
$ajaxLoad = false;
|
||||
|
||||
if (!$isIE8){
|
||||
try {
|
||||
$files = \OCA\Files_Trashbin\Helper::getTrashFiles($dir);
|
||||
} catch (Exception $e) {
|
||||
header('Location: ' . OCP\Util::linkTo('files_trashbin', 'index.php'));
|
||||
exit();
|
||||
}
|
||||
}
|
||||
else{
|
||||
$files = array();
|
||||
$ajaxLoad = true;
|
||||
}
|
||||
|
||||
$dirlisting = false;
|
||||
if ($dir && $dir !== '/') {
|
||||
$dirlisting = true;
|
||||
}
|
||||
|
||||
$breadcrumb = \OCA\Files_Trashbin\Helper::makeBreadcrumb($dir);
|
||||
|
||||
$breadcrumbNav = new OCP\Template('files_trashbin', 'part.breadcrumb', '');
|
||||
$breadcrumbNav->assign('breadcrumb', $breadcrumb);
|
||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php') . '?dir=');
|
||||
$breadcrumbNav->assign('home', OCP\Util::linkTo('files', 'index.php'));
|
||||
|
||||
$list = new OCP\Template('files_trashbin', 'part.list', '');
|
||||
$list->assign('files', $files);
|
||||
|
||||
$encodedDir = \OCP\Util::encodePath($dir);
|
||||
$list->assign('baseURL', OCP\Util::linkTo('files_trashbin', 'index.php'). '?dir='.$encodedDir);
|
||||
$list->assign('downloadURL', OCP\Util::linkTo('files_trashbin', 'download.php') . '?file='.$encodedDir);
|
||||
$list->assign('dirlisting', $dirlisting);
|
||||
$list->assign('disableDownloadActions', true);
|
||||
|
||||
$tmpl->assign('dirlisting', $dirlisting);
|
||||
$tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage());
|
||||
$tmpl->assign('fileList', $list->fetchPage());
|
||||
$tmpl->assign('files', $files);
|
||||
$tmpl->assign('dir', $dir);
|
||||
$tmpl->assign('disableSharing', true);
|
||||
$tmpl->assign('ajaxLoad', true);
|
||||
|
||||
$tmpl->printPage();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* disable download and sharing actions */
|
||||
var disableDownloadActions = true;
|
||||
var disableSharing = true;
|
||||
var trashBinApp = true;
|
||||
|
|
|
@ -1,61 +1,78 @@
|
|||
/* globals OC, FileList, t */
|
||||
// override reload with own ajax call
|
||||
FileList.reload = function(){
|
||||
FileList.showMask();
|
||||
if (FileList._reloadCall){
|
||||
FileList._reloadCall.abort();
|
||||
}
|
||||
$.ajax({
|
||||
url: OC.filePath('files_trashbin','ajax','list.php'),
|
||||
data: {
|
||||
dir : $('#dir').val(),
|
||||
breadcrumb: true
|
||||
},
|
||||
error: function(result) {
|
||||
FileList.reloadCallback(result);
|
||||
},
|
||||
success: function(result) {
|
||||
FileList.reloadCallback(result);
|
||||
/* global OC, t, FileList */
|
||||
(function() {
|
||||
FileList.appName = t('files_trashbin', 'Deleted files');
|
||||
|
||||
FileList._deletedRegExp = new RegExp(/^(.+)\.d[0-9]+$/);
|
||||
|
||||
/**
|
||||
* Convert a file name in the format filename.d12345 to the real file name.
|
||||
* This will use basename.
|
||||
* The name will not be changed if it has no ".d12345" suffix.
|
||||
* @param name file name
|
||||
* @return converted file name
|
||||
*/
|
||||
FileList.getDeletedFileName = function(name) {
|
||||
name = OC.basename(name);
|
||||
var match = FileList._deletedRegExp.exec(name);
|
||||
if (match && match.length > 1) {
|
||||
name = match[1];
|
||||
}
|
||||
});
|
||||
};
|
||||
return name;
|
||||
};
|
||||
|
||||
FileList.appName = t('files_trashbin', 'Deleted files');
|
||||
var oldSetCurrentDir = FileList._setCurrentDir;
|
||||
FileList._setCurrentDir = function(targetDir) {
|
||||
oldSetCurrentDir.apply(this, arguments);
|
||||
|
||||
FileList._deletedRegExp = new RegExp(/^(.+)\.d[0-9]+$/);
|
||||
var baseDir = OC.basename(targetDir);
|
||||
if (baseDir !== '') {
|
||||
FileList.setPageTitle(FileList.getDeletedFileName(baseDir));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a file name in the format filename.d12345 to the real file name.
|
||||
* This will use basename.
|
||||
* The name will not be changed if it has no ".d12345" suffix.
|
||||
* @param name file name
|
||||
* @return converted file name
|
||||
*/
|
||||
FileList.getDeletedFileName = function(name) {
|
||||
name = OC.basename(name);
|
||||
var match = FileList._deletedRegExp.exec(name);
|
||||
if (match && match.length > 1) {
|
||||
name = match[1];
|
||||
}
|
||||
return name;
|
||||
};
|
||||
var oldSetCurrentDir = FileList.setCurrentDir;
|
||||
FileList.setCurrentDir = function(targetDir) {
|
||||
oldSetCurrentDir.apply(this, arguments);
|
||||
var oldCreateRow = FileList._createRow;
|
||||
FileList._createRow = function() {
|
||||
// FIXME: MEGAHACK until we find a better solution
|
||||
var tr = oldCreateRow.apply(this, arguments);
|
||||
tr.find('td.filesize').remove();
|
||||
return tr;
|
||||
};
|
||||
|
||||
var baseDir = OC.basename(targetDir);
|
||||
if (baseDir !== '') {
|
||||
FileList.setPageTitle(FileList.getDeletedFileName(baseDir));
|
||||
}
|
||||
};
|
||||
FileList._onClickBreadCrumb = function(e) {
|
||||
var $el = $(e.target).closest('.crumb'),
|
||||
index = $el.index(),
|
||||
$targetDir = $el.data('dir');
|
||||
// first one is home, let the link makes it default action
|
||||
if (index !== 0) {
|
||||
e.preventDefault();
|
||||
FileList.changeDirectory($targetDir);
|
||||
}
|
||||
};
|
||||
|
||||
FileList.linkTo = function(dir){
|
||||
return OC.linkTo('files_trashbin', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/');
|
||||
}
|
||||
var oldAdd = FileList.add;
|
||||
FileList.add = function(fileData, options) {
|
||||
options = options || {};
|
||||
var dir = FileList.getCurrentDirectory();
|
||||
var dirListing = dir !== '' && dir !== '/';
|
||||
// show deleted time as mtime
|
||||
if (fileData.mtime) {
|
||||
fileData.mtime = parseInt(fileData.mtime, 10);
|
||||
}
|
||||
if (!dirListing) {
|
||||
fileData.displayName = fileData.name;
|
||||
fileData.name = fileData.name + '.d' + Math.floor(fileData.mtime / 1000);
|
||||
}
|
||||
return oldAdd.call(this, fileData, options);
|
||||
};
|
||||
|
||||
FileList.updateEmptyContent = function(){
|
||||
var $fileList = $('#fileList');
|
||||
var exists = $fileList.find('tr:first').exists();
|
||||
$('#emptycontent').toggleClass('hidden', exists);
|
||||
$('#filestable th').toggleClass('hidden', !exists);
|
||||
}
|
||||
FileList.linkTo = function(dir){
|
||||
return OC.linkTo('files_trashbin', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/');
|
||||
};
|
||||
|
||||
FileList.updateEmptyContent = function(){
|
||||
var $fileList = $('#fileList');
|
||||
var exists = $fileList.find('tr:first').exists();
|
||||
$('#emptycontent').toggleClass('hidden', exists);
|
||||
$('#filestable th').toggleClass('hidden', !exists);
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -8,9 +8,26 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* global OC, t, FileList, FileActions */
|
||||
|
||||
/* global OC, t, BreadCrumb, FileActions, FileList, Files */
|
||||
$(document).ready(function() {
|
||||
var deletedRegExp = new RegExp(/^(.+)\.d[0-9]+$/);
|
||||
|
||||
/**
|
||||
* Convert a file name in the format filename.d12345 to the real file name.
|
||||
* This will use basename.
|
||||
* The name will not be changed if it has no ".d12345" suffix.
|
||||
* @param name file name
|
||||
* @return converted file name
|
||||
*/
|
||||
function getDeletedFileName(name) {
|
||||
name = OC.basename(name);
|
||||
var match = deletedRegExp.exec(name);
|
||||
if (match && match.length > 1) {
|
||||
name = match[1];
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
function removeCallback(result) {
|
||||
if (result.status !== 'success') {
|
||||
OC.dialogs.alert(result.data.message, t('core', 'Error'));
|
||||
|
@ -18,7 +35,7 @@ $(document).ready(function() {
|
|||
|
||||
var files = result.data.success;
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
FileList.findFileEl(OC.basename(files[i].filename)).remove();
|
||||
FileList.remove(OC.basename(files[i].filename), {updateSummary: false});
|
||||
}
|
||||
FileList.updateFileSummary();
|
||||
FileList.updateEmptyContent();
|
||||
|
@ -74,7 +91,6 @@ $(document).ready(function() {
|
|||
}
|
||||
procesSelection();
|
||||
});
|
||||
|
||||
$('.undelete').click('click', function(event) {
|
||||
event.preventDefault();
|
||||
var allFiles = $('#select_all').is(':checked');
|
||||
|
@ -89,7 +105,7 @@ $(document).ready(function() {
|
|||
};
|
||||
}
|
||||
else {
|
||||
files = getSelectedFiles('name');
|
||||
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');
|
||||
|
@ -131,7 +147,7 @@ $(document).ready(function() {
|
|||
};
|
||||
}
|
||||
else {
|
||||
files = getSelectedFiles('name');
|
||||
files = Files.getSelectedFiles('name');
|
||||
params = {
|
||||
files: JSON.stringify(files),
|
||||
dir: FileList.getCurrentDirectory()
|
||||
|
@ -158,7 +174,7 @@ $(document).ready(function() {
|
|||
}
|
||||
FileList.hideMask();
|
||||
// simply remove all files
|
||||
FileList.update('');
|
||||
FileList.setFiles([]);
|
||||
enableActions();
|
||||
}
|
||||
else {
|
||||
|
@ -191,7 +207,7 @@ $(document).ready(function() {
|
|||
var filename = $(this).parent().parent().attr('data-file');
|
||||
var tr = FileList.findFileEl(filename);
|
||||
var renaming = tr.data('renaming');
|
||||
if(!renaming && !FileList.isLoading(filename)){
|
||||
if(!renaming){
|
||||
if(mime.substr(0, 5) === 'text/'){ //no texteditor for now
|
||||
return;
|
||||
}
|
||||
|
@ -203,48 +219,62 @@ $(document).ready(function() {
|
|||
action(filename);
|
||||
}
|
||||
}
|
||||
|
||||
// event handlers for breadcrumb items
|
||||
$('#controls').delegate('.crumb:not(.home) a', 'click', onClickBreadcrumb);
|
||||
});
|
||||
|
||||
/**
|
||||
* Override crumb URL maker (hacky!)
|
||||
*/
|
||||
FileList.breadcrumb.getCrumbUrl = function(part, index) {
|
||||
if (index === 0) {
|
||||
return OC.linkTo('files', 'index.php');
|
||||
}
|
||||
return OC.linkTo('files_trashbin', 'index.php')+"?dir=" + encodeURIComponent(part.dir);
|
||||
};
|
||||
|
||||
Files.generatePreviewUrl = function(urlSpec) {
|
||||
return OC.generateUrl('/apps/files_trashbin/ajax/preview.php?') + $.param(urlSpec);
|
||||
};
|
||||
|
||||
Files.getDownloadUrl = function(action, params) {
|
||||
// no downloads
|
||||
return '#';
|
||||
};
|
||||
|
||||
Files.getAjaxUrl = function(action, params) {
|
||||
var q = '';
|
||||
if (params) {
|
||||
q = '?' + OC.buildQueryString(params);
|
||||
}
|
||||
return OC.filePath('files_trashbin', 'ajax', action + '.php') + q;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Override crumb making to add "Deleted Files" entry
|
||||
* and convert files with ".d" extensions to a more
|
||||
* user friendly name.
|
||||
*/
|
||||
var oldMakeCrumbs = BreadCrumb.prototype._makeCrumbs;
|
||||
BreadCrumb.prototype._makeCrumbs = function() {
|
||||
var parts = oldMakeCrumbs.apply(this, arguments);
|
||||
// duplicate first part
|
||||
parts.unshift(parts[0]);
|
||||
parts[1] = {
|
||||
dir: '/',
|
||||
name: t('files_trashbin', 'Deleted Files')
|
||||
};
|
||||
for (var i = 2; i < parts.length; i++) {
|
||||
parts[i].name = getDeletedFileName(parts[i].name);
|
||||
}
|
||||
return parts;
|
||||
};
|
||||
|
||||
FileActions.actions.dir = {
|
||||
// only keep 'Open' action for navigation
|
||||
'Open': FileActions.actions.dir.Open
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
function getSelectedFiles(property){
|
||||
var elements=$('td.filename input:checkbox:checked').parent().parent();
|
||||
var files=[];
|
||||
elements.each(function(i,element){
|
||||
var file={
|
||||
name:$(element).attr('data-file'),
|
||||
timestamp:$(element).attr('data-timestamp'),
|
||||
type:$(element).attr('data-type')
|
||||
};
|
||||
if(property){
|
||||
files.push(file[property]);
|
||||
}else{
|
||||
files.push(file);
|
||||
}
|
||||
});
|
||||
return files;
|
||||
}
|
||||
|
||||
function fileDownloadPath(dir, file) {
|
||||
return OC.filePath('files_trashbin', '', 'download.php') + '?file='+encodeURIComponent(file);
|
||||
}
|
||||
|
||||
function enableActions() {
|
||||
$(".action").css("display", "inline");
|
||||
$(":input:checkbox").css("display", "inline");
|
||||
|
|
|
@ -27,6 +27,10 @@ class Helper
|
|||
if ($dirContent === false) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
list($storage, $internalPath) = $view->resolvePath($dir);
|
||||
$absoluteDir = $view->getAbsolutePath($dir);
|
||||
|
||||
if (is_resource($dirContent)) {
|
||||
while (($entryName = readdir($dirContent)) !== false) {
|
||||
if (!\OC\Files\Filesystem::isIgnoredDir($entryName)) {
|
||||
|
@ -40,76 +44,41 @@ class Helper
|
|||
$parts = explode('/', ltrim($dir, '/'));
|
||||
$timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1);
|
||||
}
|
||||
$result[] = array(
|
||||
'id' => $id,
|
||||
'timestamp' => $timestamp,
|
||||
'mime' => \OC_Helper::getFileNameMimeType($id),
|
||||
$i = array(
|
||||
'name' => $id,
|
||||
'mtime' => $timestamp,
|
||||
'mimetype' => \OC_Helper::getFileNameMimeType($id),
|
||||
'type' => $view->is_dir($dir . '/' . $entryName) ? 'dir' : 'file',
|
||||
'location' => $dir,
|
||||
'directory' => ($dir === '/') ? '' : $dir,
|
||||
);
|
||||
$result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i);
|
||||
}
|
||||
}
|
||||
closedir($dirContent);
|
||||
}
|
||||
|
||||
$files = array();
|
||||
$id = 0;
|
||||
list($storage, $internalPath) = $view->resolvePath($dir);
|
||||
$absoluteDir = $view->getAbsolutePath($dir);
|
||||
foreach ($result as $r) {
|
||||
$i = array();
|
||||
$i['id'] = $id++;
|
||||
$i['name'] = $r['id'];
|
||||
$i['date'] = \OCP\Util::formatDate($r['timestamp']);
|
||||
$i['timestamp'] = $r['timestamp'];
|
||||
$i['etag'] = $r['timestamp']; // add fake etag, it is only needed to identify the preview image
|
||||
$i['mimetype'] = $r['mime'];
|
||||
$i['type'] = $r['type'];
|
||||
if ($i['type'] === 'file') {
|
||||
$fileinfo = pathinfo($r['id']);
|
||||
$i['basename'] = $fileinfo['filename'];
|
||||
$i['extension'] = isset($fileinfo['extension']) ? ('.'.$fileinfo['extension']) : '';
|
||||
}
|
||||
$i['directory'] = $r['location'];
|
||||
if ($i['directory'] === '/') {
|
||||
$i['directory'] = '';
|
||||
}
|
||||
$i['permissions'] = \OCP\PERMISSION_READ;
|
||||
if (\OCP\App::isEnabled('files_encryption')) {
|
||||
$i['isPreviewAvailable'] = false;
|
||||
} else {
|
||||
$i['isPreviewAvailable'] = \OC::$server->getPreviewManager()->isMimeSupported($r['mime']);
|
||||
}
|
||||
$i['icon'] = \OCA\Files\Helper::determineIcon($i);
|
||||
$files[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i);
|
||||
}
|
||||
usort($result, array('\OCA\Files\Helper', 'fileCmp'));
|
||||
|
||||
usort($files, array('\OCA\Files\Helper', 'fileCmp'));
|
||||
|
||||
return $files;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the given path into a breadcrumb structure.
|
||||
* @param string $dir path to process
|
||||
* @return array where each entry is a hash of the absolute
|
||||
* directory path and its name
|
||||
* Format file infos for JSON
|
||||
* @param \OCP\Files\FileInfo[] $fileInfos file infos
|
||||
*/
|
||||
public static function makeBreadcrumb($dir){
|
||||
// Make breadcrumb
|
||||
$pathtohere = '';
|
||||
$breadcrumb = array();
|
||||
foreach (explode('/', $dir) as $i) {
|
||||
if ($i !== '') {
|
||||
if ( preg_match('/^(.+)\.d[0-9]+$/', $i, $match) ) {
|
||||
$name = $match[1];
|
||||
} else {
|
||||
$name = $i;
|
||||
}
|
||||
$pathtohere .= '/' . $i;
|
||||
$breadcrumb[] = array('dir' => $pathtohere, 'name' => $name);
|
||||
public static function formatFileInfos($fileInfos) {
|
||||
$files = array();
|
||||
$id = 0;
|
||||
foreach ($fileInfos as $i) {
|
||||
$entry = \OCA\Files\Helper::formatFileInfo($i);
|
||||
$entry['id'] = $id++;
|
||||
$entry['etag'] = $entry['mtime']; // add fake etag, it is only needed to identify the preview image
|
||||
$entry['permissions'] = \OCP\PERMISSION_READ;
|
||||
if (\OCP\App::isEnabled('files_encryption')) {
|
||||
$entry['isPreviewAvailable'] = false;
|
||||
}
|
||||
$files[] = $entry;
|
||||
}
|
||||
return $breadcrumb;
|
||||
return $files;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
<div id="controls">
|
||||
<?php print_unescaped($_['breadcrumb']); ?>
|
||||
<div id="file_action_panel"></div>
|
||||
<div id="file_action_panel"></div>
|
||||
</div>
|
||||
<div id='notification'></div>
|
||||
|
||||
<div id="emptycontent" <?php if (!(isset($_['files']) && count($_['files']) === 0 && $_['dirlisting'] === false && !$_['ajaxLoad'])):?>class="hidden"<?php endif; ?>><?php p($l->t('Nothing in here. Your trash bin is empty!'))?></div>
|
||||
<div id="emptycontent" class="hidden"><?php p($l->t('Nothing in here. Your trash bin is empty!'))?></div>
|
||||
|
||||
<input type="hidden" name="ajaxLoad" id="ajaxLoad" value="<?php p($_['ajaxLoad']); ?>" />
|
||||
<input type="hidden" id="disableSharing" data-status="<?php p($_['disableSharing']); ?>"></input>
|
||||
<input type="hidden" id="permissions" value="0"></input>
|
||||
<input type="hidden" name="dir" value="<?php p($_['dir']) ?>" id="dir">
|
||||
|
||||
<table id="filestable">
|
||||
|
@ -40,6 +38,5 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody id="fileList">
|
||||
<?php print_unescaped($_['fileList']); ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
<div class="crumb home">
|
||||
<a href="<?php print_unescaped($_['home']); ?>">
|
||||
<img src="<?php print_unescaped(OCP\image_path('core', 'places/home.svg'));?>" class="svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="crumb svg"
|
||||
data-dir='/'>
|
||||
<a href="<?php p($_['baseURL']); ?>"><?php p($l->t("Deleted Files")); ?></a>
|
||||
</div>
|
||||
<?php if(count($_["breadcrumb"])):?>
|
||||
<?php endif;?>
|
||||
<?php for($i=0; $i<count($_["breadcrumb"]); $i++):
|
||||
$crumb = $_["breadcrumb"][$i];
|
||||
$dir = \OCP\Util::encodePath($crumb["dir"]); ?>
|
||||
<div class="crumb <?php if($i === count($_["breadcrumb"])-1) p('last');?> svg"
|
||||
data-dir='<?php p($dir);?>'>
|
||||
<a href="<?php p($_['baseURL'].$dir); ?>"><?php p($crumb["name"]); ?></a>
|
||||
</div>
|
||||
<?php endfor;
|
|
@ -1,79 +0,0 @@
|
|||
<?php foreach($_['files'] as $file):
|
||||
$relative_deleted_date = OCP\relative_modified_date($file['timestamp']);
|
||||
// the older the file, the brighter the shade of grey; days*14
|
||||
$relative_date_color = round((time()-$file['date'])/60/60/24*14);
|
||||
if($relative_date_color>200) $relative_date_color = 200;
|
||||
$name = \OCP\Util::encodePath($file['name']);
|
||||
$directory = \OCP\Util::encodePath($file['directory']); ?>
|
||||
<tr data-filename="<?php p($file['name']);?>"
|
||||
data-type="<?php ($file['type'] === 'dir')?p('dir'):p('file')?>"
|
||||
data-mime="<?php p($file['mimetype'])?>"
|
||||
data-permissions='<?php p($file['permissions']); ?>'
|
||||
<?php if ( $_['dirlisting'] ): ?>
|
||||
id="<?php p($file['directory'].'/'.$file['name']);?>"
|
||||
data-file="<?php p($name);?>"
|
||||
data-timestamp=''
|
||||
data-dirlisting=1
|
||||
<?php else: ?>
|
||||
id="<?php p($file['name'].'.d'.$file['timestamp']);?>"
|
||||
data-file="<?php p($file['name'].'.d'.$file['timestamp']);?>"
|
||||
data-timestamp='<?php p($file['timestamp']);?>'
|
||||
data-dirlisting=0
|
||||
<?php endif; ?>>
|
||||
<?php if($file['isPreviewAvailable']): ?>
|
||||
<td class="filename svg preview-icon"
|
||||
<?php else: ?>
|
||||
<td class="filename svg"
|
||||
<?php endif; ?>
|
||||
<?php if($file['type'] === 'dir'): ?>
|
||||
style="background-image:url(<?php print_unescaped(OCP\mimetype_icon('dir')); ?>)"
|
||||
<?php else: ?>
|
||||
<?php if($file['isPreviewAvailable']): ?>
|
||||
style="background-image:url(<?php print_unescaped(OCA\Files_Trashbin\Trashbin::preview_icon(!$_['dirlisting'] ? ($file['name'].'.d'.$file['timestamp']) : ($file['directory'].'/'.$file['name']))); ?>)"
|
||||
<?php else: ?>
|
||||
style="background-image:url(<?php print_unescaped(OCP\mimetype_icon($file['mimetype'])); ?>)"
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
>
|
||||
<?php if(!isset($_['readonly']) || !$_['readonly']): ?>
|
||||
<input id="select-<?php p($file['id']); ?>" type="checkbox" />
|
||||
<label for="select-<?php p($file['id']); ?>"></label>
|
||||
<?php endif; ?>
|
||||
<?php if($file['type'] === 'dir'): ?>
|
||||
<?php if( $_['dirlisting'] ): ?>
|
||||
<a class="name dir" href="<?php p($_['baseURL'].'/'.$name); ?>" title="">
|
||||
<?php else: ?>
|
||||
<a class="name dir" href="<?php p($_['baseURL'].'/'.$name.'.d'.$file['timestamp']); ?>" title="">
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<?php if( $_['dirlisting'] ): ?>
|
||||
<a class="name file" href="<?php p($_['downloadURL'].'/'.$name); ?>" title="">
|
||||
<?php else: ?>
|
||||
<a class="name file" href="<?php p($_['downloadURL'].'/'.$name.'.d'.$file['timestamp']);?>" title="">
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<span class="nametext">
|
||||
<?php if($file['type'] === 'dir'):?>
|
||||
<?php print_unescaped(htmlspecialchars($file['name']));?>
|
||||
<?php else:?>
|
||||
<?php print_unescaped(htmlspecialchars($file['basename']));?><span
|
||||
class='extension'><?php p($file['extension']);?></span>
|
||||
<?php endif;?>
|
||||
</span>
|
||||
<?php if($file['type'] === 'dir'):?>
|
||||
<span class="uploadtext" currentUploads="0">
|
||||
</span>
|
||||
<?php endif;?>
|
||||
</a>
|
||||
</td>
|
||||
<td class="date">
|
||||
<span class="modified"
|
||||
title="<?php p($file['date']); ?>"
|
||||
style="color:rgb(<?php p($relative_date_color.','
|
||||
.$relative_date_color.','
|
||||
.$relative_date_color) ?>)">
|
||||
<?php p($relative_deleted_date); ?>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;
|
|
@ -283,6 +283,10 @@ input[type="submit"].enabled {
|
|||
padding: 7px 10px
|
||||
}
|
||||
|
||||
#controls .button.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#content { position:relative; height:100%; width:100%; }
|
||||
#content .hascontrols {
|
||||
position: relative;
|
||||
|
@ -922,6 +926,9 @@ div.crumb {
|
|||
background: url('../img/breadcrumb.svg') no-repeat right center;
|
||||
height: 44px;
|
||||
}
|
||||
div.crumb.hidden {
|
||||
display: none;
|
||||
}
|
||||
div.crumb a,
|
||||
div.crumb span {
|
||||
position: relative;
|
||||
|
|
|
@ -159,6 +159,7 @@ function escapeHTML(s) {
|
|||
* @param file The filename
|
||||
* @param dir The directory the file is in - e.g. $('#dir').val()
|
||||
* @return string
|
||||
* @deprecated use Files.getDownloadURL() instead
|
||||
*/
|
||||
function fileDownloadPath(dir, file) {
|
||||
return OC.filePath('files', 'ajax', 'download.php')+'?files='+encodeURIComponent(file)+'&dir='+encodeURIComponent(dir);
|
||||
|
@ -371,6 +372,7 @@ var OC={
|
|||
*/
|
||||
parseQueryString:function(queryString){
|
||||
var parts,
|
||||
pos,
|
||||
components,
|
||||
result = {},
|
||||
key,
|
||||
|
@ -378,12 +380,25 @@ var OC={
|
|||
if (!queryString){
|
||||
return null;
|
||||
}
|
||||
if (queryString[0] === '?'){
|
||||
queryString = queryString.substr(1);
|
||||
pos = queryString.indexOf('?');
|
||||
if (pos >= 0){
|
||||
queryString = queryString.substr(pos + 1);
|
||||
}
|
||||
parts = queryString.split('&');
|
||||
parts = queryString.replace(/\+/g, '%20').split('&');
|
||||
for (var i = 0; i < parts.length; i++){
|
||||
components = parts[i].split('=');
|
||||
// split on first equal sign
|
||||
var part = parts[i]
|
||||
pos = part.indexOf('=');
|
||||
if (pos >= 0) {
|
||||
components = [
|
||||
part.substr(0, pos),
|
||||
part.substr(pos + 1)
|
||||
]
|
||||
}
|
||||
else {
|
||||
// key only
|
||||
components = [part];
|
||||
}
|
||||
if (!components.length){
|
||||
continue;
|
||||
}
|
||||
|
@ -391,8 +406,14 @@ var OC={
|
|||
if (!key){
|
||||
continue;
|
||||
}
|
||||
value = components[1];
|
||||
result[key] = value && decodeURIComponent(value);
|
||||
// if equal sign was there, return string
|
||||
if (components.length > 1) {
|
||||
result[key] = decodeURIComponent(components[1]);
|
||||
}
|
||||
// no equal sign => null value
|
||||
else {
|
||||
result[key] = null;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
|
|
@ -294,7 +294,7 @@ var OCdialogs = {
|
|||
conflict.find('.replacement .mtime').text(formatDate(replacement.lastModifiedDate));
|
||||
}
|
||||
var path = original.directory + '/' +original.name;
|
||||
Files.lazyLoadPreview(path, original.mime, function(previewpath){
|
||||
Files.lazyLoadPreview(path, original.mimetype, function(previewpath){
|
||||
conflict.find('.original .icon').css('background-image','url('+previewpath+')');
|
||||
}, 96, 96, original.etag);
|
||||
getCroppedPreview(replacement).then(
|
||||
|
@ -514,7 +514,7 @@ var OCdialogs = {
|
|||
}
|
||||
|
||||
return $.getJSON(
|
||||
OC.filePath('files', 'ajax', 'rawlist.php'),
|
||||
OC.filePath('files', 'ajax', 'list.php'),
|
||||
{
|
||||
dir: dir,
|
||||
mimetypes: JSON.stringify(mimeType)
|
||||
|
@ -539,7 +539,7 @@ var OCdialogs = {
|
|||
this.$filelist.empty().addClass('loading');
|
||||
this.$filePicker.data('path', dir);
|
||||
$.when(this._getFileList(dir, this.$filePicker.data('mimetype'))).then(function(response) {
|
||||
$.each(response.data, function(index, file) {
|
||||
$.each(response.data.files, function(index, file) {
|
||||
if (file.type === 'dir') {
|
||||
dirs.push(file);
|
||||
} else {
|
||||
|
@ -555,9 +555,16 @@ var OCdialogs = {
|
|||
type: entry.type,
|
||||
dir: dir,
|
||||
filename: entry.name,
|
||||
date: OC.mtime2date(entry.mtime)
|
||||
date: OC.mtime2date(Math.floor(entry.mtime / 1000))
|
||||
});
|
||||
$li.find('img').attr('src', entry.mimetype_icon);
|
||||
$li.find('img').attr('src', entry.icon);
|
||||
if (entry.isPreviewAvailable) {
|
||||
var urlSpec = {
|
||||
file: dir + '/' + entry.name
|
||||
};
|
||||
var previewUrl = OC.generateUrl('/core/preview.png?') + $.param(urlSpec);
|
||||
$li.find('img').attr('src', previewUrl);
|
||||
}
|
||||
self.$filelist.append($li);
|
||||
});
|
||||
|
||||
|
|
|
@ -268,7 +268,72 @@ describe('Core base tests', function() {
|
|||
// still nothing
|
||||
expect(counter).toEqual(0);
|
||||
});
|
||||
|
||||
});
|
||||
describe('Parse query string', function() {
|
||||
it('Parses query string from full URL', function() {
|
||||
var query = OC.parseQueryString('http://localhost/stuff.php?q=a&b=x');
|
||||
expect(query).toEqual({q: 'a', b: 'x'});
|
||||
});
|
||||
it('Parses query string from query part alone', function() {
|
||||
var query = OC.parseQueryString('q=a&b=x');
|
||||
expect(query).toEqual({q: 'a', b: 'x'});
|
||||
});
|
||||
it('Returns null hash when empty query', function() {
|
||||
var query = OC.parseQueryString('');
|
||||
expect(query).toEqual(null);
|
||||
});
|
||||
it('Returns empty hash when empty query with question mark', function() {
|
||||
var query = OC.parseQueryString('?');
|
||||
expect(query).toEqual({});
|
||||
});
|
||||
it('Decodes regular query strings', function() {
|
||||
var query = OC.parseQueryString('a=abc&b=def');
|
||||
expect(query).toEqual({
|
||||
a: 'abc',
|
||||
b: 'def'
|
||||
});
|
||||
});
|
||||
it('Ignores empty parts', function() {
|
||||
var query = OC.parseQueryString('&q=a&&b=x&');
|
||||
expect(query).toEqual({q: 'a', b: 'x'});
|
||||
});
|
||||
it('Ignores lone equal signs', function() {
|
||||
var query = OC.parseQueryString('&q=a&=&b=x&');
|
||||
expect(query).toEqual({q: 'a', b: 'x'});
|
||||
});
|
||||
it('Includes extra equal signs in value', function() {
|
||||
var query = OC.parseQueryString('u=a=x&q=a=b');
|
||||
expect(query).toEqual({u: 'a=x', q: 'a=b'});
|
||||
});
|
||||
it('Decodes plus as space', function() {
|
||||
var query = OC.parseQueryString('space+key=space+value');
|
||||
expect(query).toEqual({'space key': 'space value'});
|
||||
});
|
||||
it('Decodes special characters', function() {
|
||||
var query = OC.parseQueryString('unicode=%E6%B1%89%E5%AD%97');
|
||||
expect(query).toEqual({unicode: '汉字'});
|
||||
query = OC.parseQueryString('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand');
|
||||
expect(query).toEqual({
|
||||
b: 'spaace value',
|
||||
'space key': 'normalvalue',
|
||||
'slash/this': 'amp&ersand'
|
||||
});
|
||||
});
|
||||
it('Decodes empty values', function() {
|
||||
var query = OC.parseQueryString('keywithemptystring=&keywithnostring');
|
||||
expect(query).toEqual({
|
||||
'keywithemptystring': '',
|
||||
'keywithnostring': null
|
||||
});
|
||||
});
|
||||
it('Does not interpret data types', function() {
|
||||
var query = OC.parseQueryString('booleanfalse=false&booleantrue=true&number=123');
|
||||
expect(query).toEqual({
|
||||
'booleanfalse': 'false',
|
||||
'booleantrue': 'true',
|
||||
'number': '123'
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('Generate Url', function() {
|
||||
it('returns absolute urls', function() {
|
||||
|
|
Loading…
Reference in New Issue