diff options
56 files changed, 418 insertions, 179 deletions
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 522ff627529..7c49c540d85 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -674,6 +674,12 @@ if (extension) { nameSpan.append($('<span></span>').addClass('extension').text(extension)); } + if (fileData.extraData) { + if (fileData.extraData.charAt(0) === '/') { + fileData.extraData = fileData.extraData.substr(1); + } + nameSpan.addClass('extra-data').attr('title', fileData.extraData); + } // dirs can show the number of uploaded files if (type === 'dir') { linkElem.append($('<span></span>').attr({ diff --git a/apps/files/l10n/bn_BD.php b/apps/files/l10n/bn_BD.php index eb50851c864..9573fefd023 100644 --- a/apps/files/l10n/bn_BD.php +++ b/apps/files/l10n/bn_BD.php @@ -5,6 +5,7 @@ $TRANSLATIONS = array( "Unknown error" => "অজানা জটিলতা", "Could not move %s - File with this name already exists" => "%s কে স্থানান্তর করা সম্ভব হলো না - এই নামের ফাইল বিদ্যমান", "Could not move %s" => "%s কে স্থানান্তর করা সম্ভব হলো না", +"Permission denied" => "অনুমতি দেয়া হয়নি", "File name cannot be empty." => "ফাইলের নামটি ফাঁকা রাখা যাবে না।", "\"%s\" is an invalid file name." => "\"%s\" টি একটি অননুমোদিত ফাইল নাম।", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "নামটি সঠিক নয়, '\\', '/', '<', '>', ':', '\"', '|', '?' এবং '*' অনুমোদিত নয়।", diff --git a/apps/files/l10n/el.php b/apps/files/l10n/el.php index 14896802ffd..4b51fa4ba00 100644 --- a/apps/files/l10n/el.php +++ b/apps/files/l10n/el.php @@ -5,6 +5,7 @@ $TRANSLATIONS = array( "Unknown error" => "Άγνωστο σφάλμα", "Could not move %s - File with this name already exists" => "Αδυναμία μετακίνησης του %s - υπάρχει ήδη αρχείο με αυτό το όνομα", "Could not move %s" => "Αδυναμία μετακίνησης του %s", +"Permission denied" => "Η πρόσβαση απορρίφθηκε", "File name cannot be empty." => "Το όνομα αρχείου δεν μπορεί να είναι κενό.", "\"%s\" is an invalid file name." => "Το \"%s\" είναι ένα μη έγκυρο όνομα αρχείου.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Μη έγκυρο όνομα, '\\', '/', '<', '>', ':', '\"', '|', '?' και '*' δεν επιτρέπονται.", diff --git a/apps/files/l10n/fi.php b/apps/files/l10n/fi.php deleted file mode 100644 index 43770829397..00000000000 --- a/apps/files/l10n/fi.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Save" => "tallentaa" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files/l10n/ka.php b/apps/files/l10n/ka.php deleted file mode 100644 index 544e8168c54..00000000000 --- a/apps/files/l10n/ka.php +++ /dev/null @@ -1,9 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Files" => "ფაილები", -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array(""), -"_Uploading %n file_::_Uploading %n files_" => array(""), -"Download" => "გადმოწერა" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files/lib/helper.php b/apps/files/lib/helper.php index 50b4e8338a8..a0c0aa4952e 100644 --- a/apps/files/lib/helper.php +++ b/apps/files/lib/helper.php @@ -138,6 +138,9 @@ class Helper } $entry['mountType'] = $mountType; } + if (isset($i['extraData'])) { + $entry['extraData'] = $i['extraData']; + } return $entry; } diff --git a/apps/files_encryption/l10n/bn_BD.php b/apps/files_encryption/l10n/bn_BD.php index c8bf47e8e39..65ecca64d93 100644 --- a/apps/files_encryption/l10n/bn_BD.php +++ b/apps/files_encryption/l10n/bn_BD.php @@ -3,7 +3,10 @@ $TRANSLATIONS = array( "Recovery key successfully enabled" => "পূনরুদ্ধার চাবি সার্থকভাবে কার্যকর করা হয়েছে", "Recovery key successfully disabled" => "পূনরুদ্ধার চাবি সার্থকভাবে অকার্যকর করা হয়েছে", "Password successfully changed." => "আপনার কূটশব্দটি সার্থকভাবে পরিবর্তন করা হয়েছে ", +"Missing requirements." => "প্রয়োজনানুযায়ী ঘাটতি আছে।", "Encryption" => "সংকেতায়ন", +"Enabled" => "কার্যকর", +"Disabled" => "অকার্যকর", "Change Password" => "কূটশব্দ পরিবর্তন করুন" ); $PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/apps/files_external/l10n/ast.php b/apps/files_external/l10n/ast.php index ba850e2fc3b..0aba42d38af 100644 --- a/apps/files_external/l10n/ast.php +++ b/apps/files_external/l10n/ast.php @@ -15,7 +15,9 @@ $TRANSLATIONS = array( "Amazon S3 and compliant" => "Amazon S3 y compatibilidá", "Access Key" => "Clave d'accesu", "Secret Key" => "Clave Secreta", +"Hostname" => "Nome d'agospiu", "Port" => "Puertu", +"Region" => "Rexón", "Enable SSL" => "Habilitar SSL", "Enable Path Style" => "Habilitar Estilu de ruta", "App key" => "App principal", @@ -46,6 +48,7 @@ $TRANSLATIONS = array( "Error configuring Google Drive storage" => "Fallu configurando l'almacenamientu de Google Drive", "Personal" => "Personal", "System" => "Sistema", +"(group)" => "(grupu)", "Saved" => "Guardáu", "<b>Note:</b> " => "<b>Nota:</b> ", " and " => "y", diff --git a/apps/files_external/l10n/bn_BD.php b/apps/files_external/l10n/bn_BD.php index 440852da6e5..b06b130dcb3 100644 --- a/apps/files_external/l10n/bn_BD.php +++ b/apps/files_external/l10n/bn_BD.php @@ -5,6 +5,11 @@ $TRANSLATIONS = array( "External storage" => "বাহ্যিক সংরক্ষণাগার", "Local" => "স্থানীয়", "Location" => "অবস্থান", +"Amazon S3" => "আমাজন S3", +"Key" => "কী", +"Secret" => "গোপণীয়", +"Bucket" => "বালতি", +"Secret Key" => "গোপণ চাবি", "Port" => "পোর্ট", "Region" => "এলাকা", "Host" => "হোস্ট", diff --git a/apps/files_external/l10n/ka.php b/apps/files_external/l10n/ka.php deleted file mode 100644 index f6356d2cef8..00000000000 --- a/apps/files_external/l10n/ka.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Users" => "მომხმარებლები" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_sharing/js/sharedfilelist.js b/apps/files_sharing/js/sharedfilelist.js index d29285dc1de..b99611f9bf0 100644 --- a/apps/files_sharing/js/sharedfilelist.js +++ b/apps/files_sharing/js/sharedfilelist.js @@ -181,6 +181,9 @@ file.name = OC.basename(share.file_target); file.path = OC.dirname(share.file_target); file.permissions = share.permissions; + if (file.path) { + file.extraData = share.file_target; + } } else { if (share.share_type !== OC.Share.SHARE_TYPE_LINK) { @@ -189,6 +192,9 @@ file.name = OC.basename(share.path); file.path = OC.dirname(share.path); file.permissions = OC.PERMISSION_ALL; + if (file.path) { + file.extraData = share.path; + } } return file; }) diff --git a/apps/files_sharing/l10n/bn_BD.php b/apps/files_sharing/l10n/bn_BD.php index e41483735bf..98d6c1a173a 100644 --- a/apps/files_sharing/l10n/bn_BD.php +++ b/apps/files_sharing/l10n/bn_BD.php @@ -4,6 +4,8 @@ $TRANSLATIONS = array( "Invalid or untrusted SSL certificate" => "অবৈধ বা অবিশ্বস্ত SSL সার্টিফিকেট", "Couldn't add remote share" => "দুরবর্তী ভাগাভাগি যোগ করা গেলনা", "Shared with you" => "আপনার সাথে ভাগাভাগি করেছেন", +"Shared by link" => "লিঙ্কের মাধ্যমে ভাগাভাগিকৃত", +"Remote share" => "দুরবর্তী ভাগাভাগি", "Cancel" => "বাতিল", "Shared by" => "যাদের মাঝে ভাগাভাগি করা হয়েছে", "Password" => "কূটশব্দ", diff --git a/apps/files_sharing/l10n/ka.php b/apps/files_sharing/l10n/ka.php deleted file mode 100644 index a9b046e03b6..00000000000 --- a/apps/files_sharing/l10n/ka.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Password" => "პაროლი", -"Download" => "გადმოწერა" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/l10n/ka.php b/apps/files_trashbin/l10n/ka.php deleted file mode 100644 index 70f10d7c0bf..00000000000 --- a/apps/files_trashbin/l10n/ka.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%n folder_::_%n folders_" => array(""), -"_%n file_::_%n files_" => array("") -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/apps/files_trashbin/lib/helper.php b/apps/files_trashbin/lib/helper.php index d0ca5fb1530..c2b81e3dbc8 100644 --- a/apps/files_trashbin/lib/helper.php +++ b/apps/files_trashbin/lib/helper.php @@ -35,6 +35,7 @@ class Helper $absoluteDir = $view->getAbsolutePath($dir); if (is_resource($dirContent)) { + $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($user); while (($entryName = readdir($dirContent)) !== false) { if (!\OC\Files\Filesystem::isIgnoredDir($entryName)) { $id = $entryName; @@ -47,6 +48,13 @@ class Helper $parts = explode('/', ltrim($dir, '/')); $timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1); } + $originalPath = ''; + if (isset($originalLocations[$id][$timestamp])) { + $originalPath = $originalLocations[$id][$timestamp]; + if (substr($originalPath, -1) === '/') { + $originalPath = substr($originalPath, 0, -1); + } + } $i = array( 'name' => $id, 'mtime' => $timestamp, @@ -54,6 +62,9 @@ class Helper 'type' => $view->is_dir($dir . '/' . $entryName) ? 'dir' : 'file', 'directory' => ($dir === '/') ? '' : $dir, ); + if ($originalPath) { + $i['extraData'] = $originalPath.'/'.$id; + } $result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i); } } diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php index dc90eadc8da..5f1226d89d8 100644 --- a/apps/files_trashbin/lib/trashbin.php +++ b/apps/files_trashbin/lib/trashbin.php @@ -41,6 +41,46 @@ class Trashbin { return array($uid, $filename); } + /** + * get original location of files for user + * + * @param string $user + * @return array (filename => array (timestamp => original location)) + */ + public static function getLocations($user) { + $query = \OC_DB::prepare('SELECT `id`, `timestamp`, `location`' + . ' FROM `*PREFIX*files_trash` WHERE `user`=?'); + $result = $query->execute(array($user)); + $array = array(); + while ($row = $result->fetchRow()) { + if (isset($array[$row['id']])) { + $array[$row['id']][$row['timestamp']] = $row['location']; + } else { + $array[$row['id']] = array($row['timestamp'] => $row['location']); + } + } + return $array; + } + + /** + * get original location of file + * + * @param string $user + * @param string $filename + * @param string $timestamp + * @return string original location + */ + public static function getLocation($user, $filename, $timestamp) { + $query = \OC_DB::prepare('SELECT `location` FROM `*PREFIX*files_trash`' + . ' WHERE `user`=? AND `id`=? AND `timestamp`=?'); + $result = $query->execute(array($user, $filename, $timestamp))->fetchAll(); + if (isset($result[0]['location'])) { + return $result[0]['location']; + } else { + return false; + } + } + private static function setUpTrash($user) { $view = new \OC\Files\View('/' . $user); if (!$view->is_dir('files_trashbin')) { @@ -318,13 +358,10 @@ class Trashbin { $location = ''; if ($timestamp) { - $query = \OC_DB::prepare('SELECT `location` FROM `*PREFIX*files_trash`' - . ' WHERE `user`=? AND `id`=? AND `timestamp`=?'); - $result = $query->execute(array($user, $filename, $timestamp))->fetchAll(); - if (count($result) !== 1) { + $location = self::getLocation($user, $filename, $timestamp); + if ($location === false) { \OC_Log::write('files_trashbin', 'trash bin database inconsistent!', \OC_Log::ERROR); } else { - $location = $result[0]['location']; // if location no longer exists, restore file in the root directory if ($location !== '/' && (!$view->is_dir('files' . $location) || diff --git a/apps/user_ldap/l10n/ka.php b/apps/user_ldap/l10n/ka.php deleted file mode 100644 index 23b6c93df86..00000000000 --- a/apps/user_ldap/l10n/ka.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -$TRANSLATIONS = array( -"_%s group found_::_%s groups found_" => array(""), -"_%s user found_::_%s users found_" => array(""), -"Help" => "შველა", -"Password" => "პაროლი" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/core/css/apps.css b/core/css/apps.css index 2042401489f..b84bbaa8b42 100644 --- a/core/css/apps.css +++ b/core/css/apps.css @@ -57,7 +57,7 @@ #app-navigation li:hover > a, #app-navigation .selected, #app-navigation .selected a { - background-color: #ccc; + background-color: #ddd; } #app-navigation .with-icon a, @@ -140,7 +140,7 @@ } #app-navigation > ul .collapsible.open:hover { - box-shadow: inset 0 0 3px #ccc; + box-shadow: inset 0 0 3px #ddd; } #app-navigation > ul .collapsible.open ul { @@ -189,7 +189,6 @@ position: absolute; top: 0; right: 0; - bottom: 0; z-index: 105; } @@ -335,7 +334,8 @@ #app-navigation .app-navigation-entry-edit input { border-bottom-right-radius: 0; border-top-right-radius: 0; - width: 204px; + width: 204px; /* fallback for IE8 */ + width: calc(100% - 36px); padding: 5px; margin-right: 0; height: 38px; @@ -428,27 +428,6 @@ background-color: transparent; } -/* icons */ -.folder-icon, .delete-icon, .edit-icon, .progress-icon { - background-repeat: no-repeat; - background-position: center; -} -.folder-icon { background-image: url('../img/places/folder.svg'); } -.delete-icon { background-image: url('../img/actions/delete.svg'); } -.delete-icon:hover, .delete-icon:focus { - background-image: url('../img/actions/delete-hover.svg'); -} -.edit-icon { background-image: url('../img/actions/rename.svg'); } -.progress-icon { - background-image: url('../img/loading.gif'); - background-size: 16px; - /* force show the loading icon, not only on hover */ - -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; - filter:alpha(opacity=100); - opacity: 1 !important; - display: inline !important; -} - /* buttons */ button.loading { background-image: url('../img/loading.gif'); diff --git a/core/css/fixes.css b/core/css/fixes.css index 12daf251579..5aba741b64b 100644 --- a/core/css/fixes.css +++ b/core/css/fixes.css @@ -105,3 +105,7 @@ select { overflow-y: auto; } +.ie8 #app-navigation .app-navigation-entry-edit input { + line-height: 38px; +} + diff --git a/core/css/header.css b/core/css/header.css index 0223f5f18b9..f83ef451ce6 100644 --- a/core/css/header.css +++ b/core/css/header.css @@ -42,7 +42,8 @@ } #header .logo { - background: url(../img/logo.svg) no-repeat center; + background-image: url(../img/logo.svg); + background-repeat: no-repeat; width: 252px; height: 120px; margin: 0 auto; diff --git a/core/css/styles.css b/core/css/styles.css index ad320b1eeca..7058a2bf7c2 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -679,6 +679,7 @@ label.infield { #body-login .wrapper { min-height: 100%; margin: 0 auto -70px; + width: 300px; } #body-login footer, #body-login .push { height: 70px; @@ -812,6 +813,16 @@ span.ui-icon {float: left; margin: 3px 7px 30px 0;} height: 16px; } +/* ---- TOOLTIPS ---- */ +.extra-data { + padding-right: 5px !important; +} +.tipsy-inner { + max-width: 400px !important; + overflow: hidden; + text-overflow: ellipsis; +} + /* ---- TAGS ---- */ #tagsdialog .content { width: 100%; height: 280px; diff --git a/core/js/js.js b/core/js/js.js index 89682e3013f..f35a3a1e2be 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -1097,6 +1097,7 @@ function initCore() { $('td .modified').tipsy({gravity:'s', fade:true, live:true}); $('td.lastLogin').tipsy({gravity:'s', fade:true, html:true}); $('input').tipsy({gravity:'w', fade:true}); + $('.extra-data').tipsy({gravity:'w', fade:true, live:true}); // toggle for menus $(document).on('mouseup.closemenus', function(event) { diff --git a/core/l10n/ast.php b/core/l10n/ast.php index a1f1d187882..f430928a0e7 100644 --- a/core/l10n/ast.php +++ b/core/l10n/ast.php @@ -5,6 +5,7 @@ $TRANSLATIONS = array( "Turned off maintenance mode" => "Apagáu'l mou de caltenimientu", "Updated database" => "Base de datos anovada", "Checked database schema update" => "Anovamientu del esquema de base de datos revisáu", +"Updated \"%s\" to %s" => "Anováu \"%s\" a %s", "Disabled incompatible apps: %s" => "Aplicaciones incompatibles desactivaes: %s", "No image or file provided" => "Nun s'especificó nenguna imaxe o ficheru", "Unknown filetype" => "Triba de ficheru desconocida", @@ -176,6 +177,7 @@ $TRANSLATIONS = array( "Thank you for your patience." => "Gracies pola to paciencia.", "You are accessing the server from an untrusted domain." => "Tas accediendo al sirvidor dende un dominiu non confiáu.", "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domain\" setting in config/config.php. An example configuration is provided in config/config.sample.php." => "Por favor, contauta col alministrador. Si yes l'alministrador, configura l'axuste \"trusted_domain\" en config/config.php. Hai un exemplu en config/config.sample.php.", +"Add \"%s\" as trusted domain" => "Amestáu \"%s\" como dominiu de confianza", "%s will be updated to version %s." => "%s anovaráse a la versión %s.", "The following apps will be disabled:" => "Deshabilitaránse les siguientes aplicaciones:", "The theme %s has been disabled." => "Deshabilitóse'l tema %s.", diff --git a/core/l10n/bn_BD.php b/core/l10n/bn_BD.php index d27a764c4be..d219411866d 100644 --- a/core/l10n/bn_BD.php +++ b/core/l10n/bn_BD.php @@ -4,6 +4,7 @@ $TRANSLATIONS = array( "Turned on maintenance mode" => "রক্ষণাবেক্ষণ মোড চালু হয়েছে", "Turned off maintenance mode" => "রক্ষণাবেক্ষণ মোড বন্ধ হয়েছে", "Updated database" => "ডাটাবেজ নবায়ন করা হয়েছে", +"No image or file provided" => "কোন ইমেজ বা ফাইল প্রদান করা হয়নি", "Unknown filetype" => "অজানা প্রকৃতির ফাইল", "Invalid image" => "অবৈধ চিত্র", "Sunday" => "রবিবার", diff --git a/core/l10n/ca.php b/core/l10n/ca.php index bf9e2e96a76..05d202f8e18 100644 --- a/core/l10n/ca.php +++ b/core/l10n/ca.php @@ -163,6 +163,7 @@ $TRANSLATIONS = array( "SQLite will be used as database. For larger installations we recommend to change this." => "S'utilitzarà SQLite com a base de dades. Per instal·lacions grans recomanem que la canvieu.", "Finish setup" => "Acaba la configuració", "Finishing …" => "Acabant...", +"This application requires JavaScript for correct operation. Please <a href=\"http://enable-javascript.com/\" target=\"_blank\">enable JavaScript</a> and reload the page." => "Aquesta aplicació requereix JavaScrip pel seu correcte funcionament. Si us plau <a href=\"http://enable-javascript.com/\" target=\"_blank\">Activeu JavaScript</a> i actualitzeu la pàgina.", "%s is available. Get more information on how to update." => "%s està disponible. Obtingueu més informació de com actualitzar.", "Log out" => "Surt", "Server side authentication failed!" => "L'autenticació del servidor ha fallat!", diff --git a/core/l10n/da.php b/core/l10n/da.php index 10d92338f68..bb25ee16549 100644 --- a/core/l10n/da.php +++ b/core/l10n/da.php @@ -7,7 +7,7 @@ $TRANSLATIONS = array( "Checked database schema update" => "Tjekket database schema opdatering", "Checked database schema update for apps" => "Tjekkede databaseskemaets opdatering for apps", "Updated \"%s\" to %s" => "Opdaterede \"%s\" til %s", -"Disabled incompatible apps: %s" => "Deaktiverer inkombatible apps: %s", +"Disabled incompatible apps: %s" => "Deaktiverer inkompatible apps: %s", "No image or file provided" => "Ingen fil eller billede givet", "Unknown filetype" => "Ukendt filtype", "Invalid image" => "Ugyldigt billede", diff --git a/core/l10n/fi.php b/core/l10n/fi.php deleted file mode 100644 index 956ab312337..00000000000 --- a/core/l10n/fi.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Settings" => "asetukset", -"Username" => "Käyttäjätunnus" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/core/l10n/ja.php b/core/l10n/ja.php index 588438c09c1..4c9c1f00cd0 100644 --- a/core/l10n/ja.php +++ b/core/l10n/ja.php @@ -187,6 +187,7 @@ $TRANSLATIONS = array( "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." => "データベースを確認してください。実行前にconfigフォルダーとdataフォルダーをバックアップします。", "Start update" => "アップデートを開始", "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" => "大規模なサイトの場合、ブラウザーがタイムアウトする可能性がある為、インストールディレクトリで次のコマンドを実行しても構いません。", -"This ownCloud instance is currently being updated, which may take a while." => "このownCloudインスタンスは現在アップデート中のため、しばらく時間がかかります。" +"This ownCloud instance is currently being updated, which may take a while." => "このownCloudインスタンスは現在アップデート中のため、しばらく時間がかかります。", +"This page will refresh itself when the ownCloud instance is available again." => "この画面は、ownCloud サーバーが再起動後、自動的に更新されます。" ); $PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/core/l10n/ka.php b/core/l10n/ka.php deleted file mode 100644 index 4805886c32c..00000000000 --- a/core/l10n/ka.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -$TRANSLATIONS = array( -"seconds ago" => "წამის წინ", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "დღეს", -"yesterday" => "გუშინ", -"_%n day ago_::_%n days ago_" => array(""), -"_%n month ago_::_%n months ago_" => array(""), -"_{count} file conflict_::_{count} file conflicts_" => array(""), -"Password" => "პაროლი", -"Personal" => "პერსონა", -"Users" => "მომხმარებლები", -"Admin" => "ადმინისტრატორი", -"Help" => "შველა" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php index dcf0553a4eb..da40fd83ad8 100644 --- a/core/templates/layout.guest.php +++ b/core/templates/layout.guest.php @@ -33,17 +33,20 @@ ?> <?php endforeach; ?> </head> - <body id="body-login"> + <body id="<?php p($_['bodyid']);?>"> <noscript><div id="nojavascript"><div><?php print_unescaped($l->t('This application requires JavaScript for correct operation. Please <a href="http://enable-javascript.com/" target="_blank">enable JavaScript</a> and reload the page.')); ?></div></div></noscript> <div class="wrapper"><!-- for sticky footer --> <div class="v-align"><!-- vertically centred box --> - <header><div id="header"> - <div class="logo svg"></div> - <div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div> - </div></header> - + <?php if ($_['bodyid'] === 'body-login' ): ?> + <header> + <div id="header"> + <div class="logo svg"></div> + <div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div> + </div> + </header> + <?php endif; ?> <?php print_unescaped($_['content']); ?> - <div class="push"></div><!-- for sticky footer --> + <div class="push"></div><!-- for sticky footer --> </div> </div> diff --git a/l10n/templates/core.pot b/l10n/templates/core.pot index 3c6ba63e2a6..2800e47539c 100644 --- a/l10n/templates/core.pot +++ b/l10n/templates/core.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files.pot b/l10n/templates/files.pot index 2ef6f883a91..82d553931cd 100644 --- a/l10n/templates/files.pot +++ b/l10n/templates/files.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_encryption.pot b/l10n/templates/files_encryption.pot index e78ae1046af..c9694a0a2aa 100644 --- a/l10n/templates/files_encryption.pot +++ b/l10n/templates/files_encryption.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_external.pot b/l10n/templates/files_external.pot index c68b9ab1025..b02ea048dae 100644 --- a/l10n/templates/files_external.pot +++ b/l10n/templates/files_external.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_sharing.pot b/l10n/templates/files_sharing.pot index 197d0392802..179ec537bd4 100644 --- a/l10n/templates/files_sharing.pot +++ b/l10n/templates/files_sharing.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_trashbin.pot b/l10n/templates/files_trashbin.pot index 450124e0037..eb037a885df 100644 --- a/l10n/templates/files_trashbin.pot +++ b/l10n/templates/files_trashbin.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/files_versions.pot b/l10n/templates/files_versions.pot index b8c9b82a5e5..48de23cce83 100644 --- a/l10n/templates/files_versions.pot +++ b/l10n/templates/files_versions.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/lib.pot b/l10n/templates/lib.pot index 015f6512cbe..bf320332438 100644 --- a/l10n/templates/lib.pot +++ b/l10n/templates/lib.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -40,11 +40,11 @@ msgid "" "config directory%s." msgstr "" -#: base.php:584 +#: base.php:587 msgid "Sample configuration detected" msgstr "" -#: base.php:585 +#: base.php:588 msgid "" "It has been detected that the sample configuration has been copied. This can " "break your installation and is unsupported. Please read the documentation " diff --git a/l10n/templates/private.pot b/l10n/templates/private.pot index 6d0ae55d14f..f06116cb6c1 100644 --- a/l10n/templates/private.pot +++ b/l10n/templates/private.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/settings.pot b/l10n/templates/settings.pot index d21da103aa2..e610c22c023 100644 --- a/l10n/templates/settings.pot +++ b/l10n/templates/settings.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -318,7 +318,7 @@ msgstr "" msgid "Restore encryption keys." msgstr "" -#: js/users/deleteHandler.js:166 +#: js/users/deleteHandler.js:205 msgid "Unable to delete {objName}" msgstr "" diff --git a/l10n/templates/user_ldap.pot b/l10n/templates/user_ldap.pot index 67029f3558b..f848be340f9 100644 --- a/l10n/templates/user_ldap.pot +++ b/l10n/templates/user_ldap.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/l10n/templates/user_webdavauth.pot b/l10n/templates/user_webdavauth.pot index 17d5526d956..bcfff3b44ce 100644 --- a/l10n/templates/user_webdavauth.pot +++ b/l10n/templates/user_webdavauth.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud Core 6.0.0\n" "Report-Msgid-Bugs-To: translations@owncloud.org\n" -"POT-Creation-Date: 2014-09-15 01:54-0400\n" +"POT-Creation-Date: 2014-09-16 01:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" diff --git a/lib/base.php b/lib/base.php index c113ed3b506..e21d0124b32 100644 --- a/lib/base.php +++ b/lib/base.php @@ -496,6 +496,9 @@ class OC { require_once $vendorAutoLoad; } + // initialize intl fallback is necessary + \Patchwork\Utf8\Bootup::initIntl(); + if (!defined('PHPUNIT_RUN')) { OC\Log\ErrorHandler::setLogger(OC_Log::$object); if (defined('DEBUG') and DEBUG) { diff --git a/lib/l10n/fi.php b/lib/l10n/fi.php deleted file mode 100644 index ac1f80a8f73..00000000000 --- a/lib/l10n/fi.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Settings" => "asetukset" -); -$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/lib/l10n/ka.php b/lib/l10n/ka.php deleted file mode 100644 index 04fefe8bdf1..00000000000 --- a/lib/l10n/ka.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Help" => "შველა", -"Personal" => "პერსონა", -"Users" => "მომხმარებლები", -"Admin" => "ადმინისტრატორი", -"ZIP download is turned off." => "ZIP გადმოწერა გამორთულია", -"Files" => "ფაილები", -"seconds ago" => "წამის წინ", -"_%n minute ago_::_%n minutes ago_" => array(""), -"_%n hour ago_::_%n hours ago_" => array(""), -"today" => "დღეს", -"yesterday" => "გუშინ", -"_%n day go_::_%n days ago_" => array(""), -"_%n month ago_::_%n months ago_" => array("") -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/lib/private/image.php b/lib/private/image.php index 7ddc8dca143..bab91745c05 100644 --- a/lib/private/image.php +++ b/lib/private/image.php @@ -450,6 +450,9 @@ class OC_Image { case IMAGETYPE_GIF: if (imagetypes() & IMG_GIF) { $this->resource = imagecreatefromgif($imagePath); + // Preserve transparency + imagealphablending($this->resource, true); + imagesavealpha($this->resource, true); } else { OC_Log::write('core', 'OC_Image->loadFromFile, GIF images not supported: '.$imagePath, @@ -468,6 +471,9 @@ class OC_Image { case IMAGETYPE_PNG: if (imagetypes() & IMG_PNG) { $this->resource = imagecreatefrompng($imagePath); + // Preserve transparency + imagealphablending($this->resource, true); + imagesavealpha($this->resource, true); } else { OC_Log::write('core', 'OC_Image->loadFromFile, PNG images not supported: '.$imagePath, diff --git a/lib/private/ocs/result.php b/lib/private/ocs/result.php index 567fe7f87fe..c5bd1d7a69e 100644 --- a/lib/private/ocs/result.php +++ b/lib/private/ocs/result.php @@ -5,19 +5,9 @@ * @author Tom Needham * @copyright 2012 Tom Needham tom@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/>. -* +* This file is licensed under the Affero General Public License version 3 or +* later. +* See the COPYING-README file. */ class OC_OCS_Result{ @@ -27,6 +17,8 @@ class OC_OCS_Result{ /** * create the OCS_Result object * @param mixed $data the data to return + * @param int $code + * @param null|string $message */ public function __construct($data=null, $code=100, $message=null) { if ($data === null) { @@ -44,7 +36,7 @@ class OC_OCS_Result{ * optionally set the total number of items available * @param int $items */ - public function setTotalItems(int $items) { + public function setTotalItems($items) { $this->items = $items; } @@ -52,7 +44,7 @@ class OC_OCS_Result{ * optionally set the the number of items per page * @param int $items */ - public function setItemsPerPage(int $items) { + public function setItemsPerPage($items) { $this->perPage = $items; } @@ -92,7 +84,7 @@ class OC_OCS_Result{ } /** - * return bool if the method succedded + * return bool Whether the method succeeded * @return bool */ public function succeeded() { diff --git a/lib/private/preview.php b/lib/private/preview.php index 086d9c0272a..d6bff961a73 100755 --- a/lib/private/preview.php +++ b/lib/private/preview.php @@ -322,7 +322,7 @@ class Preview { if($fileInfo !== null && $fileInfo !== false) { $fileId = $fileInfo->getId(); - $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; + $previewPath = $this->getPreviewPath($fileId); $this->userView->deleteAll($previewPath); return $this->userView->rmdir($previewPath); } @@ -392,7 +392,7 @@ class Preview { return array(); } - $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; + $previewPath = $this->getPreviewPath($fileId); $wantedAspectRatio = (float) ($this->getMaxX() / $this->getMaxY()); @@ -509,7 +509,7 @@ class Preview { $this->preview = $preview; $this->resizeAndCrop(); - $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; + $previewPath = $this->getPreviewPath($fileId); $cachePath = $this->buildCachePath($fileId); if ($this->userView->is_dir($this->getThumbnailsFolder() . '/') === false) { @@ -797,12 +797,22 @@ class Preview { $maxX = $this->getMaxX(); $maxY = $this->getMaxY(); - $previewPath = $this->getThumbnailsFolder() . '/' . $fileId . '/'; - $preview = $previewPath . $maxX . '-' . $maxY . '.png'; + $previewPath = $this->getPreviewPath($fileId); + $preview = $previewPath . strval($maxX) . '-' . strval($maxY); if ($this->keepAspect) { - $preview = $previewPath . $maxX . '-with-aspect.png'; - return $preview; + $preview .= '-with-aspect'; } + $preview .= '.png'; + return $preview; } + + + /** + * @param int $fileId + * @return string + */ + private function getPreviewPath($fileId) { + return $this->getThumbnailsFolder() . '/' . $fileId . '/'; + } } diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index b9a97186945..1de47ded3b3 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -63,6 +63,7 @@ class OC_TemplateLayout extends OC_Template { parent::__construct('core', 'layout.guest', '', false); } else if ($renderas == 'guest') { parent::__construct('core', 'layout.guest'); + $this->assign('bodyid', 'body-login'); } else { parent::__construct('core', 'layout.base'); } diff --git a/lib/private/util.php b/lib/private/util.php index a130d997ca3..79f3eb7b48c 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -1402,13 +1402,11 @@ class OC_Util { * @return bool|string */ public static function normalizeUnicode($value) { - if (class_exists('Patchwork\PHP\Shim\Normalizer')) { - $normalizedValue = \Patchwork\PHP\Shim\Normalizer::normalize($value); - if ($normalizedValue === false) { - \OC_Log::write('core', 'normalizing failed for "' . $value . '"', \OC_Log::WARN); - } else { - $value = $normalizedValue; - } + $normalizedValue = normalizer_normalize($value); + if ($normalizedValue === null || $normalizedValue === false) { + \OC_Log::write('core', 'normalizing failed for "' . $value . '"', \OC_Log::WARN); + } else { + $value = $normalizedValue; } return $value; diff --git a/settings/js/users/deleteHandler.js b/settings/js/users/deleteHandler.js index d4736d88701..c89a844044e 100644 --- a/settings/js/users/deleteHandler.js +++ b/settings/js/users/deleteHandler.js @@ -35,6 +35,16 @@ function DeleteHandler(endpoint, paramID, markCallback, removeCallback) { } /** + * Number of milliseconds after which the operation is performed. + */ +DeleteHandler.TIMEOUT_MS = 7000; + +/** + * Timer after which the action will be performed anyway. + */ +DeleteHandler.prototype._timeout = null; + +/** * The function to be called after successfully marking the object for deletion * @callback markCallback * @param {string} oid the ID of the specific user or group @@ -72,7 +82,9 @@ DeleteHandler.prototype.setNotification = function(notifier, dataID, message, un var dh = this; - $('#notification').on('click', '.undo', function () { + $('#notification') + .off('click.deleteHandler_' + dataID) + .on('click.deleteHandler_' + dataID, '.undo', function () { if ($('#notification').data(dh.notificationDataID)) { var oid = dh.oidToDelete; dh.cancel(); @@ -116,18 +128,36 @@ DeleteHandler.prototype.hideNotification = function() { */ DeleteHandler.prototype.mark = function(oid) { if(this.oidToDelete !== false) { - this.deleteEntry(); + // passing true to avoid hiding the notification + // twice and causing the second notification + // to disappear immediately + this.deleteEntry(true); } this.oidToDelete = oid; this.canceled = false; this.markCallback(oid); this.showNotification(); + if (this._timeout) { + clearTimeout(this._timeout); + this._timeout = null; + } + if (DeleteHandler.TIMEOUT_MS > 0) { + this._timeout = window.setTimeout( + _.bind(this.deleteEntry, this), + DeleteHandler.TIMEOUT_MS + ); + } }; /** * cancels a delete operation */ DeleteHandler.prototype.cancel = function() { + if (this._timeout) { + clearTimeout(this._timeout); + this._timeout = null; + } + this.canceled = true; this.oidToDelete = false; }; @@ -137,22 +167,31 @@ DeleteHandler.prototype.cancel = function() { * initialized by mark(). On error, it will show a message via * OC.dialogs.alert. On success, a callback is fired so that the client can * update the web interface accordingly. + * + * @param {boolean} [keepNotification] true to keep the notification, false to hide + * it, defaults to false */ -DeleteHandler.prototype.deleteEntry = function() { +DeleteHandler.prototype.deleteEntry = function(keepNotification) { if(this.canceled || this.oidToDelete === false) { return false; } var dh = this; - if($('#notification').data(this.notificationDataID) === true) { + if(!keepNotification && $('#notification').data(this.notificationDataID) === true) { dh.hideNotification(); } + if (this._timeout) { + clearTimeout(this._timeout); + this._timeout = null; + } + var payload = {}; payload[dh.ajaxParamID] = dh.oidToDelete; $.ajax({ type: 'POST', url: OC.filePath('settings', 'ajax', dh.ajaxEndpoint), + // FIXME: do not use synchronous ajax calls as they block the browser ! async: false, data: payload, success: function (result) { diff --git a/settings/l10n/bn_BD.php b/settings/l10n/bn_BD.php index b15cc143bfc..be67c187834 100644 --- a/settings/l10n/bn_BD.php +++ b/settings/l10n/bn_BD.php @@ -5,6 +5,7 @@ $TRANSLATIONS = array( "test email settings" => "ইমেইল নিয়ামকসমূহ পরীক্ষা করুন", "If you received this email, the settings seem to be correct." => "এই ইমেইলের অর্থ নিয়ামকসমূহ সঠিক।", "Email sent" => "ই-মেইল পাঠানো হয়েছে", +"Send mode" => "পাঠানো মোড", "Encryption" => "সংকেতায়ন", "Unable to load list from App Store" => "অ্যাপস্টোর থেকে তালিকা লোড করতে সক্ষম নয়", "Authentication error" => "অনুমোদন ঘটিত সমস্যা", diff --git a/settings/l10n/ka.php b/settings/l10n/ka.php deleted file mode 100644 index e9024a3c1c9..00000000000 --- a/settings/l10n/ka.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Password" => "პაროლი" -); -$PLURAL_FORMS = "nplurals=1; plural=0;"; diff --git a/settings/tests/js/users/deleteHandlerSpec.js b/settings/tests/js/users/deleteHandlerSpec.js new file mode 100644 index 00000000000..6b6328be801 --- /dev/null +++ b/settings/tests/js/users/deleteHandlerSpec.js @@ -0,0 +1,185 @@ +/** +* 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/>. +* +*/ + +describe('DeleteHandler tests', function() { + var showNotificationSpy; + var hideNotificationSpy; + var clock; + var removeCallback; + var markCallback; + var undoCallback; + + function init(markCallback, removeCallback, undoCallback) { + var handler = new DeleteHandler('dummyendpoint.php', 'paramid', markCallback, removeCallback); + handler.setNotification(OC.Notification, 'dataid', 'removed %oid entry', undoCallback); + return handler; + } + + beforeEach(function() { + showNotificationSpy = sinon.spy(OC.Notification, 'showHtml'); + hideNotificationSpy = sinon.spy(OC.Notification, 'hide'); + clock = sinon.useFakeTimers(); + removeCallback = sinon.stub(); + markCallback = sinon.stub(); + undoCallback = sinon.stub(); + + $('#testArea').append('<div id="notification"></div>'); + }); + afterEach(function() { + showNotificationSpy.restore(); + hideNotificationSpy.restore(); + clock.restore(); + }); + it('shows a notification when marking for delete', function() { + var handler = init(markCallback, removeCallback, undoCallback); + handler.mark('some_uid'); + + expect(showNotificationSpy.calledOnce).toEqual(true); + expect(showNotificationSpy.getCall(0).args[0]).toEqual('removed some_uid entry'); + + expect(markCallback.calledOnce).toEqual(true); + expect(markCallback.getCall(0).args[0]).toEqual('some_uid'); + expect(removeCallback.notCalled).toEqual(true); + expect(undoCallback.notCalled).toEqual(true); + + expect(fakeServer.requests.length).toEqual(0); + }); + it('deletes first entry and reshows notification on second delete', function() { + var handler = init(markCallback, removeCallback, undoCallback); + handler.mark('some_uid'); + + expect(showNotificationSpy.calledOnce).toEqual(true); + expect(showNotificationSpy.getCall(0).args[0]).toEqual('removed some_uid entry'); + showNotificationSpy.reset(); + + handler.mark('some_other_uid'); + + expect(hideNotificationSpy.calledOnce).toEqual(true); + expect(showNotificationSpy.calledOnce).toEqual(true); + expect(showNotificationSpy.getCall(0).args[0]).toEqual('removed some_other_uid entry'); + + expect(markCallback.calledTwice).toEqual(true); + expect(markCallback.getCall(0).args[0]).toEqual('some_uid'); + expect(markCallback.getCall(1).args[0]).toEqual('some_other_uid'); + expect(removeCallback.notCalled).toEqual(true); + expect(undoCallback.notCalled).toEqual(true); + + // previous one was delete + expect(fakeServer.requests.length).toEqual(1); + var request = fakeServer.requests[0]; + expect(request.url).toEqual(OC.webroot + '/index.php/settings/ajax/dummyendpoint.php'); + }); + it('automatically deletes after timeout', function() { + var handler = init(markCallback, removeCallback, undoCallback); + handler.mark('some_uid'); + + clock.tick(5000); + // nothing happens yet + expect(fakeServer.requests.length).toEqual(0); + + clock.tick(3000); + expect(fakeServer.requests.length).toEqual(1); + var request = fakeServer.requests[0]; + expect(request.url).toEqual(OC.webroot + '/index.php/settings/ajax/dummyendpoint.php'); + }); + it('deletes when deleteEntry is called', function() { + var handler = init(markCallback, removeCallback, undoCallback); + handler.mark('some_uid'); + + handler.deleteEntry(); + expect(fakeServer.requests.length).toEqual(1); + var request = fakeServer.requests[0]; + expect(request.url).toEqual(OC.webroot + '/index.php/settings/ajax/dummyendpoint.php'); + }); + it('cancels deletion when undo is clicked', function() { + var handler = init(markCallback, removeCallback, undoCallback); + handler.setNotification(OC.Notification, 'dataid', 'removed %oid entry <span class="undo">Undo</span>', undoCallback); + handler.mark('some_uid'); + $('#notification .undo').click(); + + expect(undoCallback.calledOnce).toEqual(true); + + // timer was cancelled + clock.tick(10000); + expect(fakeServer.requests.length).toEqual(0); + }); + it('cancels deletion when cancel method is called', function() { + var handler = init(markCallback, removeCallback, undoCallback); + handler.setNotification(OC.Notification, 'dataid', 'removed %oid entry <span class="undo">Undo</span>', undoCallback); + handler.mark('some_uid'); + handler.cancel(); + + // not sure why, seems to be by design + expect(undoCallback.notCalled).toEqual(true); + + // timer was cancelled + clock.tick(10000); + expect(fakeServer.requests.length).toEqual(0); + }); + it('calls removeCallback after successful server side deletion', function() { + fakeServer.respondWith(/\/index\.php\/settings\/ajax\/dummyendpoint.php/, [ + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({status: 'success'}) + ]); + + var handler = init(markCallback, removeCallback, undoCallback); + handler.mark('some_uid'); + handler.deleteEntry(); + + expect(fakeServer.requests.length).toEqual(1); + var request = fakeServer.requests[0]; + var query = OC.parseQueryString(request.requestBody); + expect(query.paramid).toEqual('some_uid'); + + expect(removeCallback.calledOnce).toEqual(true); + expect(undoCallback.notCalled).toEqual(true); + expect(removeCallback.getCall(0).args[0]).toEqual('some_uid'); + }); + it('calls undoCallback and shows alert after failed server side deletion', function() { + // stub t to avoid extra calls + var tStub = sinon.stub(window, 't').returns('text'); + fakeServer.respondWith(/\/index\.php\/settings\/ajax\/dummyendpoint.php/, [ + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({status: 'error', data: {message: 'test error'}}) + ]); + + var alertDialogStub = sinon.stub(OC.dialogs, 'alert'); + var handler = init(markCallback, removeCallback, undoCallback); + handler.mark('some_uid'); + handler.deleteEntry(); + + expect(fakeServer.requests.length).toEqual(1); + var request = fakeServer.requests[0]; + var query = OC.parseQueryString(request.requestBody); + expect(query.paramid).toEqual('some_uid'); + + expect(removeCallback.notCalled).toEqual(true); + expect(undoCallback.calledOnce).toEqual(true); + expect(undoCallback.getCall(0).args[0]).toEqual('some_uid'); + + expect(alertDialogStub.calledOnce); + + alertDialogStub.restore(); + tStub.restore(); + }); +}); diff --git a/tests/karma.config.js b/tests/karma.config.js index 14a0d7e8464..357fcf3f122 100644 --- a/tests/karma.config.js +++ b/tests/karma.config.js @@ -66,7 +66,15 @@ module.exports = function(config) { 'apps/files_external/js/mountsfilelist.js' ], testFiles: ['apps/files_external/tests/js/*.js'] - }]; + }, + { + name: 'settings', + srcFiles: [ + 'settings/js/users/deleteHandler.js' + ], + testFiles: ['settings/tests/js/users/deleteHandlerSpec.js'] + } + ]; } // respect NOCOVERAGE env variable diff --git a/tests/lib/image.php b/tests/lib/image.php index 131a9d86f3e..795bc464159 100644 --- a/tests/lib/image.php +++ b/tests/lib/image.php @@ -115,6 +115,9 @@ class Test_Image extends PHPUnit_Framework_TestCase { public function testData() { $img = new \OC_Image(OC::$SERVERROOT.'/tests/data/testimage.png'); $raw = imagecreatefromstring(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.png')); + // Preserve transparency + imagealphablending($raw, true); + imagesavealpha($raw, true); ob_start(); imagepng($raw); $expected = ob_get_clean(); |