aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/js')
-rw-r--r--apps/files/js/fileactions.js45
-rw-r--r--apps/files/js/filelist.js30
-rw-r--r--apps/files/js/files.js105
-rw-r--r--apps/files/js/keyboardshortcuts.js165
4 files changed, 260 insertions, 85 deletions
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index 82d990bf780..80b9c01f838 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -70,34 +70,43 @@ var FileActions = {
}
parent.children('a.name').append('<span class="fileactions" />');
var defaultAction = FileActions.getDefault(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions());
- for (name in actions) {
+
+ var actionHandler = function (event) {
+ event.stopPropagation();
+ event.preventDefault();
+
+ FileActions.currentFile = event.data.elem;
+ var file = FileActions.getCurrentFile();
+
+ event.data.actionFunc(file);
+ };
+
+ $.each(actions, function (name, action) {
// NOTE: Temporary fix to prevent rename action in root of Shared directory
if (name === 'Rename' && $('#dir').val() === '/Shared') {
- continue;
+ return true;
}
- if ((name === 'Download' || actions[name] !== defaultAction) && name !== 'Delete') {
+
+ if ((name === 'Download' || action !== defaultAction) && name !== 'Delete') {
var img = FileActions.icons[name];
if (img.call) {
img = img(file);
}
var html = '<a href="#" class="action" data-action="'+name+'">';
if (img) {
- html += '<img class ="svg" src="' + img + '"/> ';
+ html += '<img class ="svg" src="' + img + '" /> ';
}
html += t('files', name) + '</a>';
+
var element = $(html);
element.data('action', name);
- element.click(function (event) {
- FileActions.currentFile = $(this).parent().parent().parent();
- event.stopPropagation();
- event.preventDefault();
- var action = actions[$(this).data('action')];
- var currentFile = FileActions.getCurrentFile();
- action(currentFile);
- });
+ //alert(element);
+ element.on('click',{a:null, elem:parent, actionFunc:actions[name]},actionHandler);
parent.find('a.name>span.fileactions').append(element);
}
- }
+
+ });
+
if (actions['Delete']) {
var img = FileActions.icons['Delete'];
if (img.call) {
@@ -113,14 +122,8 @@ var FileActions = {
if (img) {
element.append($('<img class ="svg" src="' + img + '"/>'));
}
- element.data('action', 'Delete');
- element.click(function (event) {
- event.stopPropagation();
- event.preventDefault();
- var action = actions[$(this).data('action')];
- var currentFile = FileActions.getCurrentFile();
- action(currentFile);
- });
+ element.data('action', actions['Delete']);
+ element.on('click',{a:null, elem:parent, actionFunc:actions['Delete']},actionHandler);
parent.parent().children().last().append(element);
}
},
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index f08e412921e..96dd0323d29 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -32,14 +32,16 @@ var FileList={
html+='<td class="date"><span class="modified" title="'+formatDate(lastModified)+'" style="color:rgb('+modifiedColor+','+modifiedColor+','+modifiedColor+')">'+relative_modified_date(lastModified.getTime() / 1000)+'</span></td>';
html+='</tr>';
FileList.insertElement(name,'file',$(html).attr('data-file',name));
+ var row = $('tr').filterAttr('data-file',name);
if(loading){
- $('tr').filterAttr('data-file',name).data('loading',true);
+ row.data('loading',true);
}else{
- $('tr').filterAttr('data-file',name).find('td.filename').draggable(dragOptions);
+ row.find('td.filename').draggable(dragOptions);
}
if (hidden) {
- $('tr').filterAttr('data-file', name).hide();
+ row.hide();
}
+ FileActions.display(row.find('td.filename'));
},
addDir:function(name,size,lastModified,hidden){
var html, td, link_elem, sizeColor, lastModifiedTime, modifiedColor;
@@ -66,11 +68,13 @@ var FileList={
td.append($('<span></span>').attr({ "class": "modified", "title": formatDate(lastModified), "style": 'color:rgb('+modifiedColor+','+modifiedColor+','+modifiedColor+')' }).text( relative_modified_date(lastModified.getTime() / 1000) ));
html.append(td);
FileList.insertElement(name,'dir',html);
- $('tr').filterAttr('data-file',name).find('td.filename').draggable(dragOptions);
- $('tr').filterAttr('data-file',name).find('td.filename').droppable(folderDropOptions);
+ var row = $('tr').filterAttr('data-file',name);
+ row.find('td.filename').draggable(dragOptions);
+ row.find('td.filename').droppable(folderDropOptions);
if (hidden) {
- $('tr').filterAttr('data-file', name).hide();
+ row.hide();
}
+ FileActions.display(row.find('td.filename'));
},
refresh:function(data) {
var result = jQuery.parseJSON(data.responseText);
@@ -85,7 +89,6 @@ var FileList={
$('tr').filterAttr('data-file',name).remove();
if($('tr[data-file]').length==0){
$('#emptyfolder').show();
- $('.file_upload_filename').addClass('highlight');
}
},
insertElement:function(name,type,element){
@@ -114,7 +117,6 @@ var FileList={
$('#fileList').append(element);
}
$('#emptyfolder').hide();
- $('.file_upload_filename').removeClass('highlight');
},
loadingDone:function(name, id){
var mime, tr=$('tr').filterAttr('data-file',name);
@@ -137,7 +139,7 @@ var FileList={
tr=$('tr').filterAttr('data-file',name);
tr.data('renaming',true);
td=tr.children('td.filename');
- input=$('<input class="filename"></input>').val(name);
+ input=$('<input class="filename"/>').val(name);
form=$('<form></form>');
form.append(input);
td.children('a.name').hide();
@@ -147,6 +149,9 @@ var FileList={
event.stopPropagation();
event.preventDefault();
var newname=input.val();
+ if (Files.containsInvalidCharacters(newname)) {
+ return false;
+ }
if (newname != name) {
if (FileList.checkName(name, newname, false)) {
newname = name;
@@ -156,11 +161,11 @@ var FileList={
OC.dialogs.alert(result.data.message, 'Error moving file');
newname = name;
}
- tr.data('renaming',false);
});
}
}
+ tr.data('renaming',false);
tr.attr('data-file', newname);
var path = td.children('a.name').attr('href');
td.children('a.name').attr('href', path.replace(encodeURIComponent(name), encodeURIComponent(newname)));
@@ -283,7 +288,7 @@ var FileList={
},
finishDelete:function(ready,sync){
if(!FileList.deleteCanceled && FileList.deleteFiles){
- var fileNames=FileList.deleteFiles.join(';');
+ var fileNames=JSON.stringify(FileList.deleteFiles);
$.ajax({
url: OC.filePath('files', 'ajax', 'delete.php'),
async:!sync,
@@ -375,4 +380,7 @@ $(document).ready(function(){
FileList.lastAction();
}
});
+ $(window).unload(function (){
+ $(window).trigger('beforeunload');
+ });
});
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 2d9ccba424a..33c775fc8ec 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -25,18 +25,27 @@ Files={
delete uploadingFiles[index];
});
procesSelection();
+ },
+ containsInvalidCharacters:function (name) {
+ var invalid_characters = ['\\', '/', '<', '>', ':', '"', '|', '?', '*'];
+ for (var i = 0; i < invalid_characters.length; i++) {
+ if (name.indexOf(invalid_characters[i]) != -1) {
+ $('#notification').text(t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed."));
+ $('#notification').fadeIn();
+ return true;
+ }
+ }
+ $('#notification').fadeOut();
+ return false;
}
};
$(document).ready(function() {
+ Files.bindKeyboardShortcuts(document, jQuery);
$('#fileList tr').each(function(){
//little hack to set unescape filenames in attribute
$(this).attr('data-file',decodeURIComponent($(this).attr('data-file')));
});
- if($('tr[data-file]').length==0){
- $('.file_upload_filename').addClass('highlight');
- }
-
$('#file_action_panel').attr('activeAction', false);
//drag/drop of files
@@ -57,8 +66,8 @@ $(document).ready(function() {
}
// Triggers invisible file input
- $('.file_upload_button_wrapper').live('click', function() {
- $(this).parent().children('.file_upload_start').trigger('click');
+ $('#upload a').live('click', function() {
+ $(this).parent().children('#file_upload_start').trigger('click');
return false;
});
@@ -159,12 +168,6 @@ $(document).ready(function() {
procesSelection();
});
- $('#file_newfolder_name').click(function(){
- if($('#file_newfolder_name').val() == 'New Folder'){
- $('#file_newfolder_name').val('');
- }
- });
-
$('.download').click('click',function(event) {
var files=getSelectedFiles('name').join(';');
var dir=$('#dir').val()||'/';
@@ -192,16 +195,16 @@ $(document).ready(function() {
e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone
});
- if ( document.getElementById("data-upload-form") ) {
+ if ( document.getElementById('data-upload-form') ) {
$(function() {
- $('.file_upload_start').fileupload({
+ $('#file_upload_start').fileupload({
dropZone: $('#content'), // restrict dropZone to content div
add: function(e, data) {
var files = data.files;
var totalSize=0;
if(files){
for(var i=0;i<files.length;i++){
- if(files[i].size ==0 || files[i].type== '')
+ if(files[i].size ==0 && files[i].type== '')
{
OC.dialogs.alert(t('files', 'Unable to upload your file as it is a directory or has 0 bytes'), t('files', 'Upload Error'));
return;
@@ -209,7 +212,7 @@ $(document).ready(function() {
totalSize+=files[i].size;
if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file
FileList.finishDelete(function(){
- $('.file_upload_start').change();
+ $('#file_upload_start').change();
});
return;
}
@@ -219,13 +222,21 @@ $(document).ready(function() {
$( '#uploadsize-message' ).dialog({
modal: true,
buttons: {
- Close: function() {
- $( this ).dialog( 'close' );
+ Close: {
+ text:t('files', 'Close'),
+ click:function() {
+ $( this ).dialog( 'close' );
+ }
}
}
});
}else{
- var date=new Date();
+ var dropTarget = $(e.originalEvent.target).closest('tr');
+ if(dropTarget && dropTarget.attr('data-type') === 'dir') { // drag&drop upload to folder
+ var dirName = dropTarget.attr('data-file')
+ }
+
+ var date=new Date();
if(files){
for(var i=0;i<files.length;i++){
if(files[i].size>0){
@@ -274,11 +285,14 @@ $(document).ready(function() {
var fileName = files[i].name
var dropTarget = $(e.originalEvent.target).closest('tr');
if(dropTarget && dropTarget.attr('data-type') === 'dir') { // drag&drop upload to folder
- var dirName = dropTarget.attr('data-file');
- var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i],
+ var dirName = dropTarget.attr('data-file')
+ var jqXHR = $('#file_upload_start').fileupload('send', {files: files[i],
formData: function(form) {
var formArray = form.serializeArray();
- formArray[1]['value'] = dirName;
+ // array index 0 contains the max files size
+ // array index 1 contains the request token
+ // array index 2 contains the directory
+ formArray[2]['value'] = dirName;
return formArray;
}}).success(function(result, textStatus, jqXHR) {
var response;
@@ -288,7 +302,13 @@ $(document).ready(function() {
$('#notification').fadeIn();
}
var file=response[0];
+ // TODO: this doesn't work if the file name has been changed server side
delete uploadingFiles[dirName][file.name];
+ if ($.assocArraySize(uploadingFiles[dirName]) == 0) {
+ delete uploadingFiles[dirName];
+ }
+
+ var uploadtext = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName).find('.uploadtext')
var currentUploads = parseInt(uploadtext.attr('currentUploads'));
currentUploads -= 1;
uploadtext.attr('currentUploads', currentUploads);
@@ -327,7 +347,7 @@ $(document).ready(function() {
}
uploadingFiles[dirName][fileName] = jqXHR;
} else {
- var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i]})
+ var jqXHR = $('#file_upload_start').fileupload('send', {files: files[i]})
.success(function(result, textStatus, jqXHR) {
var response;
response=jQuery.parseJSON(result);
@@ -424,7 +444,7 @@ $(document).ready(function() {
//add multiply file upload attribute to all browsers except konqueror (which crashes when it's used)
if(navigator.userAgent.search(/konqueror/i)==-1){
- $('.file_upload_start').attr('multiple','multiple')
+ $('#file_upload_start').attr('multiple','multiple')
}
//if the breadcrumb is to long, start by replacing foldernames with '...' except for the current folder
@@ -452,7 +472,6 @@ $(document).ready(function() {
$(window).click(function(){
$('#new>ul').hide();
$('#new').removeClass('active');
- $('button.file_upload_filename').removeClass('active');
$('#new li').each(function(i,element){
if($(element).children('p').length==0){
$(element).children('input').remove();
@@ -466,7 +485,6 @@ $(document).ready(function() {
$('#new>a').click(function(){
$('#new>ul').toggle();
$('#new').toggleClass('active');
- $('button.file_upload_filename').toggleClass('active');
});
$('#new li').click(function(){
if($(this).children('p').length==0){
@@ -488,8 +506,10 @@ $(document).ready(function() {
$(this).append(input);
input.focus();
input.change(function(){
- if(type != 'web' && $(this).val().indexOf('/')!=-1){
- $('#notification').text(t('files','Invalid name, \'/\' is not allowed.'));
+ if (type != 'web' && Files.containsInvalidCharacters($(this).val())) {
+ return;
+ } else if( type == 'folder' && $('#dir').val() == '/' && $(this).val() == 'Shared') {
+ $('#notification').text(t('files','Invalid folder name. Usage of "Shared" is reserved by Owncloud'));
$('#notification').fadeIn();
return;
}
@@ -699,7 +719,7 @@ function updateBreadcrumb(breadcrumbHtml) {
//options for file drag/dropp
var dragOptions={
- distance: 20, revert: 'invalid', opacity: 0.7,
+ distance: 20, revert: 'invalid', opacity: 0.7, helper: 'clone',
stop: function(event, ui) {
$('#fileList tr td.filename').addClass('ui-draggable');
}
@@ -722,7 +742,7 @@ var folderDropOptions={
}
var crumbDropOptions={
drop: function( event, ui ) {
- var file=ui.draggable.text().trim();
+ var file=ui.draggable.parent().data('file');
var target=$(this).data('dir');
var dir=$('#dir').val();
while(dir.substr(0,1)=='/'){//remove extra leading /'s
@@ -818,7 +838,7 @@ function getSelectedFiles(property){
name:$(element).attr('data-file'),
mime:$(element).data('mime'),
type:$(element).data('type'),
- size:$(element).data('size'),
+ size:$(element).data('size')
};
if(property){
files.push(file[property]);
@@ -829,32 +849,11 @@ function getSelectedFiles(property){
return files;
}
-function relative_modified_date(timestamp) {
- var timediff = Math.round((new Date()).getTime() / 1000) - timestamp;
- var diffminutes = Math.round(timediff/60);
- var diffhours = Math.round(diffminutes/60);
- var diffdays = Math.round(diffhours/24);
- var diffmonths = Math.round(diffdays/31);
- if(timediff < 60) { return t('files','seconds ago'); }
- else if(timediff < 120) { return t('files','1 minute ago'); }
- else if(timediff < 3600) { return t('files','{minutes} minutes ago',{minutes: diffminutes}); }
- //else if($timediff < 7200) { return '1 hour ago'; }
- //else if($timediff < 86400) { return $diffhours.' hours ago'; }
- else if(timediff < 86400) { return t('files','today'); }
- else if(timediff < 172800) { return t('files','yesterday'); }
- else if(timediff < 2678400) { return t('files','{days} days ago',{days: diffdays}); }
- else if(timediff < 5184000) { return t('files','last month'); }
- //else if($timediff < 31556926) { return $diffmonths.' months ago'; }
- else if(timediff < 31556926) { return t('files','months ago'); }
- else if(timediff < 63113852) { return t('files','last year'); }
- else { return t('files','years ago'); }
-}
-
function getMimeIcon(mime, ready){
if(getMimeIcon.cache[mime]){
ready(getMimeIcon.cache[mime]);
}else{
- $.get( OC.filePath('files','ajax','mimeicon.php')+'?mime='+mime, function(path){
+ $.get( OC.filePath('files','ajax','mimeicon.php'), {mime: mime}, function(path){
getMimeIcon.cache[mime]=path;
ready(getMimeIcon.cache[mime]);
});
diff --git a/apps/files/js/keyboardshortcuts.js b/apps/files/js/keyboardshortcuts.js
new file mode 100644
index 00000000000..562755f55b7
--- /dev/null
+++ b/apps/files/js/keyboardshortcuts.js
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2012 Erik Sargent <esthepiking at gmail dot com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ */
+/*****************************
+ * Keyboard shortcuts for Files app
+ * ctrl/cmd+n: new folder
+ * ctrl/cmd+shift+n: new file
+ * esc (while new file context menu is open): close menu
+ * up/down: select file/folder
+ * enter: open file/folder
+ * delete/backspace: delete file/folder
+ *****************************/
+var Files = Files || {};
+(function(Files) {
+ var keys = [];
+ var keyCodes = {
+ shift: 16,
+ n: 78,
+ cmdFirefox: 224,
+ cmdOpera: 17,
+ leftCmdWebKit: 91,
+ rightCmdWebKit: 93,
+ ctrl: 17,
+ esc: 27,
+ downArrow: 40,
+ upArrow: 38,
+ enter: 13,
+ del: 46
+ };
+
+ function removeA(arr) {
+ var what, a = arguments,
+ L = a.length,
+ ax;
+ while (L > 1 && arr.length) {
+ what = a[--L];
+ while ((ax = arr.indexOf(what)) !== -1) {
+ arr.splice(ax, 1);
+ }
+ }
+ return arr;
+ }
+
+ function newFile() {
+ $("#new").addClass("active");
+ $(".popup.popupTop").toggle(true);
+ $('#new li[data-type="file"]').trigger('click');
+ removeA(keys, keyCodes.n);
+ }
+
+ function newFolder() {
+ $("#new").addClass("active");
+ $(".popup.popupTop").toggle(true);
+ $('#new li[data-type="folder"]').trigger('click');
+ removeA(keys, keyCodes.n);
+ }
+
+ function esc() {
+ $("#controls").trigger('click');
+ }
+
+ function down() {
+ var select = -1;
+ $("#fileList tr").each(function(index) {
+ if ($(this).hasClass("mouseOver")) {
+ select = index + 1;
+ $(this).removeClass("mouseOver");
+ }
+ });
+ if (select === -1) {
+ $("#fileList tr:first").addClass("mouseOver");
+ } else {
+ $("#fileList tr").each(function(index) {
+ if (index === select) {
+ $(this).addClass("mouseOver");
+ }
+ });
+ }
+ }
+
+ function up() {
+ var select = -1;
+ $("#fileList tr").each(function(index) {
+ if ($(this).hasClass("mouseOver")) {
+ select = index - 1;
+ $(this).removeClass("mouseOver");
+ }
+ });
+ if (select === -1) {
+ $("#fileList tr:last").addClass("mouseOver");
+ } else {
+ $("#fileList tr").each(function(index) {
+ if (index === select) {
+ $(this).addClass("mouseOver");
+ }
+ });
+ }
+ }
+
+ function enter() {
+ $("#fileList tr").each(function(index) {
+ if ($(this).hasClass("mouseOver")) {
+ $(this).removeClass("mouseOver");
+ $(this).find("span.nametext").trigger('click');
+ }
+ });
+ }
+
+ function del() {
+ $("#fileList tr").each(function(index) {
+ if ($(this).hasClass("mouseOver")) {
+ $(this).removeClass("mouseOver");
+ $(this).find("a.action.delete").trigger('click');
+ }
+ });
+ }
+
+ function rename() {
+ $("#fileList tr").each(function(index) {
+ if ($(this).hasClass("mouseOver")) {
+ $(this).removeClass("mouseOver");
+ $(this).find("a[data-action='Rename']").trigger('click');
+ }
+ });
+ }
+ Files.bindKeyboardShortcuts = function(document, $) {
+ $(document).keydown(function(event) { //check for modifier keys
+ var preventDefault = false;
+ if ($.inArray(event.keyCode, keys) === -1) keys.push(event.keyCode);
+ if (
+ $.inArray(keyCodes.n, keys) !== -1 && ($.inArray(keyCodes.cmdFirefox, keys) !== -1 || $.inArray(keyCodes.cmdOpera, keys) !== -1 || $.inArray(keyCodes.leftCmdWebKit, keys) !== -1 || $.inArray(keyCodes.rightCmdWebKit, keys) !== -1 || $.inArray(keyCodes.ctrl, keys) !== -1 || event.ctrlKey)) {
+ preventDefault = true; //new file/folder prevent browser from responding
+ }
+ if (preventDefault) {
+ event.preventDefault(); //Prevent web browser from responding
+ event.stopPropagation();
+ return false;
+ }
+ });
+ $(document).keyup(function(event) {
+ // do your event.keyCode checks in here
+ if (
+ $.inArray(keyCodes.n, keys) !== -1 && ($.inArray(keyCodes.cmdFirefox, keys) !== -1 || $.inArray(keyCodes.cmdOpera, keys) !== -1 || $.inArray(keyCodes.leftCmdWebKit, keys) !== -1 || $.inArray(keyCodes.rightCmdWebKit, keys) !== -1 || $.inArray(keyCodes.ctrl, keys) !== -1 || event.ctrlKey)) {
+ if ($.inArray(keyCodes.shift, keys) !== -1) { //16=shift, New File
+ newFile();
+ } else { //New Folder
+ newFolder();
+ }
+ } else if ($("#new").hasClass("active") && $.inArray(keyCodes.esc, keys) !== -1) { //close new window
+ esc();
+ } else if ($.inArray(keyCodes.downArrow, keys) !== -1) { //select file
+ down();
+ } else if ($.inArray(keyCodes.upArrow, keys) !== -1) { //select file
+ up();
+ } else if (!$("#new").hasClass("active") && $.inArray(keyCodes.enter, keys) !== -1) { //open file
+ enter();
+ } else if (!$("#new").hasClass("active") && $.inArray(keyCodes.del, keys) !== -1) { //delete file
+ del();
+ }
+ removeA(keys, event.keyCode);
+ });
+ };
+})(Files); \ No newline at end of file