diff options
author | Jan-Christoph Borchardt <hey@jancborchardt.net> | 2012-12-18 15:41:58 +0100 |
---|---|---|
committer | Jan-Christoph Borchardt <hey@jancborchardt.net> | 2012-12-18 15:41:58 +0100 |
commit | 586cc9a83b27f54647c3425403cfcfa0cd9210c2 (patch) | |
tree | 61305f81a41e0380b65da0fcb20b738ef813d8f6 /apps/files/js | |
parent | b05666219e43e59cfeab13a53b992cf71ad8bfad (diff) | |
parent | dd5e39ca71d80c97e1b62427642ba1a08f75624d (diff) | |
download | nextcloud-server-586cc9a83b27f54647c3425403cfcfa0cd9210c2.tar.gz nextcloud-server-586cc9a83b27f54647c3425403cfcfa0cd9210c2.zip |
merge master into navigation
Diffstat (limited to 'apps/files/js')
-rw-r--r-- | apps/files/js/fileactions.js | 45 | ||||
-rw-r--r-- | apps/files/js/filelist.js | 30 | ||||
-rw-r--r-- | apps/files/js/files.js | 105 | ||||
-rw-r--r-- | apps/files/js/keyboardshortcuts.js | 165 |
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 |