diff options
Diffstat (limited to 'apps/files/js')
-rw-r--r-- | apps/files/js/fileactions.js | 14 | ||||
-rw-r--r-- | apps/files/js/filelist.js | 45 | ||||
-rw-r--r-- | apps/files/js/files.js | 200 | ||||
-rw-r--r-- | apps/files/js/jquery-visibility.js | 32 | ||||
-rw-r--r-- | apps/files/js/publiclistview.php | 20 |
5 files changed, 226 insertions, 85 deletions
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js index 80b9c01f838..f5ee363a4c8 100644 --- a/apps/files/js/fileactions.js +++ b/apps/files/js/fileactions.js @@ -70,23 +70,23 @@ var FileActions = { } parent.children('a.name').append('<span class="fileactions" />'); var defaultAction = FileActions.getDefault(FileActions.getCurrentMimeType(), FileActions.getCurrentType(), FileActions.getCurrentPermissions()); - + 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') { return true; } - + if ((name === 'Download' || action !== defaultAction) && name !== 'Delete') { var img = FileActions.icons[name]; if (img.call) { @@ -97,16 +97,16 @@ var FileActions = { html += '<img class ="svg" src="' + img + '" /> '; } html += t('files', name) + '</a>'; - + var element = $(html); element.data('action', name); //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) { diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 96dd0323d29..04b7d92e2c3 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -149,10 +149,9 @@ var FileList={ event.stopPropagation(); event.preventDefault(); var newname=input.val(); - if (Files.containsInvalidCharacters(newname)) { + if (!Files.isFileNameValid(newname)) { return false; - } - if (newname != name) { + } else if (newname != name) { if (FileList.checkName(name, newname, false)) { newname = name; } else { @@ -185,6 +184,13 @@ var FileList={ td.children('a.name').show(); return false; }); + input.keyup(function(event){ + if (event.keyCode == 27) { + tr.data('renaming',false); + form.remove(); + td.children('a.name').show(); + } + }); input.click(function(event){ event.stopPropagation(); event.preventDefault(); @@ -195,15 +201,14 @@ var FileList={ }, checkName:function(oldName, newName, isNewFile) { if (isNewFile || $('tr').filterAttr('data-file', newName).length > 0) { - if (isNewFile) { - $('#notification').html(t('files', '{new_name} already exists', {new_name: escapeHTML(newName)})+'<span class="replace">'+t('files', 'replace')+'</span><span class="suggest">'+t('files', 'suggest name')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>'); - } else { - $('#notification').html(t('files', '{new_name} already exists', {new_name: escapeHTML(newName)})+'<span class="replace">'+t('files', 'replace')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>'); - } $('#notification').data('oldName', oldName); $('#notification').data('newName', newName); $('#notification').data('isNewFile', isNewFile); - $('#notification').fadeIn(); + if (isNewFile) { + OC.Notification.showHtml(t('files', '{new_name} already exists', {new_name: escapeHTML(newName)})+'<span class="replace">'+t('files', 'replace')+'</span><span class="suggest">'+t('files', 'suggest name')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>'); + } else { + OC.Notification.showHtml(t('files', '{new_name} already exists', {new_name: escapeHTML(newName)})+'<span class="replace">'+t('files', 'replace')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>'); + } return true; } else { return false; @@ -245,11 +250,10 @@ var FileList={ FileList.finishReplace(); }; if (isNewFile) { - $('#notification').html(t('files', 'replaced {new_name}', {new_name: newName})+'<span class="undo">'+t('files', 'undo')+'</span>'); + OC.Notification.showHtml(t('files', 'replaced {new_name}', {new_name: newName})+'<span class="undo">'+t('files', 'undo')+'</span>'); } else { - $('#notification').html(t('files', 'replaced {new_name} with {old_name}', {new_name: newName}, {old_name: oldName})+'<span class="undo">'+t('files', 'undo')+'</span>'); + OC.Notification.showHtml(t('files', 'replaced {new_name} with {old_name}', {new_name: newName}, {old_name: oldName})+'<span class="undo">'+t('files', 'undo')+'</span>'); } - $('#notification').fadeIn(); }, finishReplace:function() { if (!FileList.replaceCanceled && FileList.replaceOldName && FileList.replaceNewName) { @@ -279,11 +283,10 @@ var FileList={ } else { // NOTE: Temporary fix to change the text to unshared for files in root of Shared folder if ($('#dir').val() == '/Shared') { - $('#notification').html(t('files', 'unshared {files}', {'files': escapeHTML(files)})+'<span class="undo">'+t('files', 'undo')+'</span>'); + OC.Notification.showHtml(t('files', 'unshared {files}', {'files': escapeHTML(files)})+'<span class="undo">'+t('files', 'undo')+'</span>'); } else { - $('#notification').html(t('files', 'deleted {files}', {'files': escapeHTML(files)})+'<span class="undo">'+t('files', 'undo')+'</span>'); + OC.Notification.showHtml(t('files', 'deleted {files}', {'files': escapeHTML(files)})+'<span class="undo">'+t('files', 'undo')+'</span>'); } - $('#notification').fadeIn(); } }, finishDelete:function(ready,sync){ @@ -296,7 +299,7 @@ var FileList={ data: {dir:$('#dir').val(),files:fileNames}, complete: function(data){ boolOperationFinished(data, function(){ - $('#notification').fadeOut('400'); + OC.Notification.hide(); $.each(FileList.deleteFiles,function(index,file){ FileList.remove(file); }); @@ -356,16 +359,16 @@ $(document).ready(function(){ FileList.replaceIsNewFile = null; } FileList.lastAction = null; - $('#notification').fadeOut('400'); + OC.Notification.hide(); }); $('#notification .replace').live('click', function() { - $('#notification').fadeOut('400', function() { - FileList.replace($('#notification').data('oldName'), $('#notification').data('newName'), $('#notification').data('isNewFile')); - }); + OC.Notification.hide(function() { + FileList.replace($('#notification').data('oldName'), $('#notification').data('newName'), $('#notification').data('isNewFile')); + }); }); $('#notification .suggest').live('click', function() { $('tr').filterAttr('data-file', $('#notification').data('oldName')).show(); - $('#notification').fadeOut('400'); + OC.Notification.hide(); }); $('#notification .cancel').live('click', function() { if ($('#notification').data('isNewFile')) { diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 6a37d9e7f53..6486468eafd 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -26,21 +26,65 @@ Files={ }); procesSelection(); }, - containsInvalidCharacters:function (name) { + updateMaxUploadFilesize:function(response) { + if(response == undefined) { + return; + } + if(response.data !== undefined && response.data.uploadMaxFilesize !== undefined) { + $('#max_upload').val(response.data.uploadMaxFilesize); + $('#upload.button').attr('original-title', response.data.maxHumanFilesize); + $('#usedSpacePercent').val(response.data.usedSpacePercent); + Files.displayStorageWarnings(); + } + if(response[0] == undefined) { + return; + } + if(response[0].uploadMaxFilesize !== undefined) { + $('#max_upload').val(response[0].uploadMaxFilesize); + $('#upload.button').attr('original-title', response[0].maxHumanFilesize); + $('#usedSpacePercent').val(response[0].usedSpacePercent); + Files.displayStorageWarnings(); + } + + }, + isFileNameValid:function (name) { + if (name === '.') { + OC.Notification.show(t('files', '\'.\' is an invalid file name.')); + return false; + } + if (name.length == 0) { + OC.Notification.show(t('files', 'File name cannot be empty.')); + return false; + } + + // check for invalid characters 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; + OC.Notification.show(t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed.")); + return false; } } - $('#notification').fadeOut(); - return false; + OC.Notification.hide(); + return true; + }, + displayStorageWarnings: function() { + if (!OC.Notification.isHidden()) { + return; + } + + var usedSpacePercent = $('#usedSpacePercent').val(); + if (usedSpacePercent > 98) { + OC.Notification.show(t('files', 'Your storage is full, files can not be updated or synced anymore!')); + return; + } + if (usedSpacePercent > 90) { + OC.Notification.show(t('files', 'Your storage is almost full ({usedSpacePercent}%)', {usedSpacePercent: usedSpacePercent})); + } } }; $(document).ready(function() { - Files.bindKeyboardShortcuts(document, jQuery); + 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'))); @@ -75,8 +119,8 @@ $(document).ready(function() { // Sets the file link behaviour : $('td.filename a').live('click',function(event) { - event.preventDefault(); if (event.ctrlKey || event.shiftKey) { + event.preventDefault(); if (event.shiftKey) { var last = $(lastChecked).parent().parent().prevAll().length; var first = $(this).parent().parent().prevAll().length; @@ -118,6 +162,7 @@ $(document).ready(function() { var permissions = $(this).parent().parent().data('permissions'); var action=FileActions.getDefault(mime,type, permissions); if(action){ + event.preventDefault(); action(filename); } } @@ -171,8 +216,7 @@ $(document).ready(function() { $('.download').click('click',function(event) { var files=getSelectedFiles('name').join(';'); var dir=$('#dir').val()||'/'; - $('#notification').text(t('files','generating ZIP-file, it may take some time.')); - $('#notification').fadeIn(); + OC.Notification.show(t('files','Your download is being prepared. This might take some time if the files are big.')); // use special download URL if provided, e.g. for public shared files if ( (downloadURL = document.getElementById("downloadURL")) ) { window.location=downloadURL.value+"&download&files="+files; @@ -234,12 +278,12 @@ $(document).ready(function() { } }); }else{ - 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 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(); + var date=new Date(); if(files){ for(var i=0;i<files.length;i++){ if(files[i].size>0){ @@ -292,26 +336,27 @@ $(document).ready(function() { var jqXHR = $('#file_upload_start').fileupload('send', {files: files[i], formData: function(form) { var formArray = form.serializeArray(); - // array index 0 contains the max files size - // array index 1 contains the request token - // array index 2 contains the directory + // 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; response=jQuery.parseJSON(result); if(response[0] == undefined || response[0].status != 'success') { - $('#notification').text(t('files', response.data.message)); - $('#notification').fadeIn(); + OC.Notification.show(t('files', response.data.message)); } + Files.updateMaxUploadFilesize(response); var file=response[0]; - // TODO: this doesn't work if the file name has been changed server side + // 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]; - } + if ($.assocArraySize(uploadingFiles[dirName]) == 0) { + delete uploadingFiles[dirName]; + } + //TODO update file upload size limit - var uploadtext = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName).find('.uploadtext') + 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); @@ -339,9 +384,8 @@ $(document).ready(function() { } else { uploadtext.text(t('files', '{count} files uploading', {count: currentUploads})); } - $('#notification').hide(); - $('#notification').text(t('files', 'Upload cancelled.')); - $('#notification').fadeIn(); + delete uploadingFiles[dirName][fileName]; + OC.Notification.show(t('files', 'Upload cancelled.')); } }); //TODO test with filenames containing slashes @@ -354,6 +398,8 @@ $(document).ready(function() { .success(function(result, textStatus, jqXHR) { var response; response=jQuery.parseJSON(result); + Files.updateMaxUploadFilesize(response); + if(response[0] != undefined && response[0].status == 'success') { var file=response[0]; delete uploadingFiles[file.name]; @@ -362,21 +408,21 @@ $(document).ready(function() { if(size==t('files','Pending')){ $('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size); } + //TODO update file upload size limit FileList.loadingDone(file.name, file.id); } else { - $('#notification').text(t('files', response.data.message)); - $('#notification').fadeIn(); + Files.cancelUpload(this.files[0].name); + OC.Notification.show(t('files', response.data.message)); $('#fileList > tr').not('[data-mime]').fadeOut(); $('#fileList > tr').not('[data-mime]').remove(); } - }) - .error(function(jqXHR, textStatus, errorThrown) { - if(errorThrown === 'abort') { - $('#notification').hide(); - $('#notification').text(t('files', 'Upload cancelled.')); - $('#notification').fadeIn(); - } - }); + }) + .error(function(jqXHR, textStatus, errorThrown) { + if(errorThrown === 'abort') { + Files.cancelUpload(this.files[0].name); + OC.Notification.show(t('files', 'Upload cancelled.')); + } + }); uploadingFiles[uniqueName] = jqXHR; } } @@ -384,6 +430,7 @@ $(document).ready(function() { data.submit().success(function(data, status) { // in safari data is a string response = jQuery.parseJSON(typeof data === 'string' ? data : data[0].body.innerText); + Files.updateMaxUploadFilesize(response); if(response[0] != undefined && response[0].status == 'success') { var file=response[0]; delete uploadingFiles[file.name]; @@ -392,10 +439,11 @@ $(document).ready(function() { if(size==t('files','Pending')){ $('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size); } + //TODO update file upload size limit FileList.loadingDone(file.name, file.id); } else { - $('#notification').text(t('files', response.data.message)); - $('#notification').fadeIn(); + //TODO Files.cancelUpload(/*where do we get the filename*/); + OC.Notification.show(t('files', response.data.message)); $('#fileList > tr').not('[data-mime]').fadeOut(); $('#fileList > tr').not('[data-mime]').remove(); } @@ -434,7 +482,7 @@ $(document).ready(function() { // http://stackoverflow.com/a/6700/11236 var size = 0, key; for (key in obj) { - if (obj.hasOwnProperty(key)) size++; + if (obj.hasOwnProperty(key)) size++; } return size; }; @@ -477,7 +525,7 @@ $(document).ready(function() { $('#new').removeClass('active'); $('#new li').each(function(i,element){ if($(element).children('p').length==0){ - $(element).children('input').remove(); + $(element).children('form').remove(); $(element).append('<p>'+$(element).data('text')+'</p>'); } }); @@ -496,7 +544,7 @@ $(document).ready(function() { $('#new li').each(function(i,element){ if($(element).children('p').length==0){ - $(element).children('input').remove(); + $(element).children('form').remove(); $(element).append('<p>'+$(element).data('text')+'</p>'); } }); @@ -505,23 +553,30 @@ $(document).ready(function() { var text=$(this).children('p').text(); $(this).data('text',text); $(this).children('p').remove(); + var form=$('<form></form>'); var input=$('<input>'); - $(this).append(input); + form.append(input); + $(this).append(form); input.focus(); - input.change(function(){ - 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; + form.submit(function(event){ + event.stopPropagation(); + event.preventDefault(); + var newname=input.val(); + if(type == 'web' && newname.length == 0) { + OC.Notification.show(t('files', 'URL cannot be empty.')); + return false; + } else if (type != 'web' && !Files.isFileNameValid(newname)) { + return false; + } else if( type == 'folder' && $('#dir').val() == '/' && newname == 'Shared') { + OC.Notification.show(t('files','Invalid folder name. Usage of \'Shared\' is reserved by Owncloud')); + return false; } if (FileList.lastAction) { FileList.lastAction(); } - var name = getUniqueName($(this).val()); - if (name != $(this).val()) { - FileList.checkName(name, $(this).val(), true); + var name = getUniqueName(newname); + if (newname != name) { + FileList.checkName(name, newname, true); var hidden = true; } else { var hidden = false; @@ -565,7 +620,7 @@ $(document).ready(function() { break; case 'web': if(name.substr(0,8)!='https://' && name.substr(0,7)!='http://'){ - name='http://'.name; + name='http://'+name; } var localName=name; if(localName.substr(localName.length-1,1)=='/'){//strip / @@ -604,8 +659,8 @@ $(document).ready(function() { }); break; } - var li=$(this).parent(); - $(this).remove(); + var li=form.parent(); + form.remove(); li.append('<p>'+li.data('text')+'</p>'); $('#new>a').click(); }); @@ -683,6 +738,36 @@ $(document).ready(function() { }); resizeBreadcrumbs(true); + + // display storage warnings + setTimeout ( "Files.displayStorageWarnings()", 100 ); + OC.Notification.setDefault(Files.displayStorageWarnings); + + // file space size sync + function update_storage_statistics() { + $.getJSON(OC.filePath('files','ajax','getstoragestats.php'),function(response) { + Files.updateMaxUploadFilesize(response); + }); + } + + // start on load - we ask the server every 5 minutes + var update_storage_statistics_interval = 5*60*1000; + var update_storage_statistics_interval_id = setInterval(update_storage_statistics, update_storage_statistics_interval); + + // Use jquery-visibility to de-/re-activate file stats sync + if ($.support.pageVisibility) { + $(document).on({ + 'show.visibility': function() { + if (!update_storage_statistics_interval_id) { + update_storage_statistics_interval_id = setInterval(update_storage_statistics, update_storage_statistics_interval); + } + }, + 'hide.visibility': function() { + clearInterval(update_storage_statistics_interval_id); + update_storage_statistics_interval_id = 0; + } + }); + } }); function scanFiles(force,dir){ @@ -712,6 +797,7 @@ scanFiles.scanning=false; function boolOperationFinished(data, callback) { result = jQuery.parseJSON(data.responseText); + Files.updateMaxUploadFilesize(result); if(result.status == 'success'){ callback.call(); } else { diff --git a/apps/files/js/jquery-visibility.js b/apps/files/js/jquery-visibility.js new file mode 100644 index 00000000000..a824bf68730 --- /dev/null +++ b/apps/files/js/jquery-visibility.js @@ -0,0 +1,32 @@ +/*! http://mths.be/visibility v1.0.5 by @mathias */ +(function (window, document, $, undefined) { + + var prefix, + property, +// In Opera, `'onfocusin' in document == true`, hence the extra `hasFocus` check to detect IE-like behavior + eventName = 'onfocusin' in document && 'hasFocus' in document ? 'focusin focusout' : 'focus blur', + prefixes = ['', 'moz', 'ms', 'o', 'webkit'], + $support = $.support, + $event = $.event; + + while ((property = prefix = prefixes.pop()) != undefined) { + property = (prefix ? prefix + 'H' : 'h') + 'idden'; + if ($support.pageVisibility = typeof document[property] == 'boolean') { + eventName = prefix + 'visibilitychange'; + break; + } + } + + $(/blur$/.test(eventName) ? window : document).on(eventName, function (event) { + var type = event.type, + originalEvent = event.originalEvent, + toElement = originalEvent.toElement; +// If it’s a `{focusin,focusout}` event (IE), `fromElement` and `toElement` should both be `null` or `undefined`; +// else, the page visibility hasn’t changed, but the user just clicked somewhere in the doc. +// In IE9, we need to check the `relatedTarget` property instead. + if (!/^focus./.test(type) || (toElement == undefined && originalEvent.fromElement == undefined && originalEvent.relatedTarget == undefined)) { + $event.trigger((property && document[property] || /^(?:blur|focusout)$/.test(type) ? 'hide' : 'show') + '.visibility'); + } + }); + +}(this, document, jQuery)); diff --git a/apps/files/js/publiclistview.php b/apps/files/js/publiclistview.php new file mode 100644 index 00000000000..f1c67aabb48 --- /dev/null +++ b/apps/files/js/publiclistview.php @@ -0,0 +1,20 @@ +<?php +/** + * Copyright (c) 2013 Lukas Reschke <lukas@statuscode.ch> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +// Set the content type to Javascript +header("Content-type: text/javascript"); + +// Disallow caching +header("Cache-Control: no-cache, must-revalidate"); +header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); + +if ( array_key_exists('disableSharing', $_) && $_['disableSharing'] == true ) { + echo "var disableSharing = true;"; +} else { + echo "var disableSharing = false;"; +} |