From 48a457df472f34429074c3ff2c6cbe00d0daf3fc Mon Sep 17 00:00:00 2001 From: Andres Michelena Klapper Date: Wed, 26 Feb 2020 14:20:52 +0100 Subject: [PATCH 1/4] added fullscreen modal package --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d3488ed..06dc1c0 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "bower-asset/ng-file-upload": "^12.0.1", "bower-asset/ngclipboard": "^1.1.1", "kartik-v/yii2-widget-select2": "^2.0.0", - "rmrevin/yii2-fontawesome": "~2.9" + "rmrevin/yii2-fontawesome": "~2.9", + "yii2assets/yii2-fullscreen-modal": "^1.0.2" }, "extra": { "bootstrap": "hrzg\\filemanager\\Bootstrap", From 038fe7f1b1f1525db5b205a8919a483df85d7066 Mon Sep 17 00:00:00 2001 From: amk Date: Fri, 4 Sep 2020 16:07:53 +0200 Subject: [PATCH 2/4] filemanager preview and preview view update --- src/assets/dist/angular-filemanager.min.js | 2967 ++++++++++---------- src/widgets/FileManagerWidget.php | 11 + 2 files changed, 1501 insertions(+), 1477 deletions(-) diff --git a/src/assets/dist/angular-filemanager.min.js b/src/assets/dist/angular-filemanager.min.js index 3f55af6..6b100e2 100755 --- a/src/assets/dist/angular-filemanager.min.js +++ b/src/assets/dist/angular-filemanager.min.js @@ -24,13 +24,13 @@ if(leftBorder>=window.innerWidth-width){ leftBorder-=width; } - + menu.hide().css( { - position: 'fixed', + position: 'fixed', left: leftBorder, top: e.pageY-offset.top }).show(); - + e.preventDefault(); }); @@ -56,7 +56,7 @@ return undefined; }; } - + })(window, angular, jQuery); (function(angular, $) { @@ -65,302 +65,283 @@ '$scope', '$rootScope', '$window', '$translate', '$http', 'fileManagerConfig', 'item', 'fileNavigator', 'apiMiddleware', function($scope, $rootScope, $window, $translate, $http, fileManagerConfig, Item, FileNavigator, ApiMiddleware) { - var $storage = $window.localStorage; - $scope.config = fileManagerConfig; - $scope.reverse = false; - $scope.predicate = ['model.type', 'model.name']; - $scope.order = function(predicate) { - $scope.reverse = ($scope.predicate[1] === predicate) ? !$scope.reverse : false; - $scope.predicate[1] = predicate; - }; - $scope.query = ''; - $scope.fileNavigator = new FileNavigator(); - $scope.apiMiddleware = new ApiMiddleware(); - $scope.uploadFileList = []; - $scope.viewTemplate = $storage.getItem('viewTemplate') || 'main-icons.html'; - $scope.fileList = []; - $scope.temps = []; - - $scope.$watch('temps', function() { - if ($scope.singleSelection()) { - $scope.temp = $scope.singleSelection(); - } else { - $scope.temp = new Item({rights: 644}); - $scope.temp.multiple = true; - } - $scope.temp.revert(); - }); + var $storage = $window.localStorage; + $scope.config = fileManagerConfig; + $scope.reverse = false; + $scope.predicate = ['model.type', 'model.name']; + $scope.order = function(predicate) { + $scope.reverse = ($scope.predicate[1] === predicate) ? !$scope.reverse : false; + $scope.predicate[1] = predicate; + }; + $scope.query = ''; + $scope.fileNavigator = new FileNavigator(); + $scope.apiMiddleware = new ApiMiddleware(); + $scope.uploadFileList = []; + $scope.viewTemplate = $storage.getItem('viewTemplate') || 'main-icons.html'; + $scope.fileList = []; + $scope.temps = []; + + $scope.$watch('temps', function() { + if ($scope.singleSelection()) { + $scope.temp = $scope.singleSelection(); + } else { + $scope.temp = new Item({rights: 644}); + $scope.temp.multiple = true; + } + $scope.temp.revert(); + }); - $scope.fileNavigator.onRefresh = function() { - $scope.temps = []; - $scope.query = ''; - $rootScope.selectedModalPath = $scope.fileNavigator.currentPath; - }; + $scope.fileNavigator.onRefresh = function() { + $scope.temps = []; + $scope.query = ''; + $rootScope.selectedModalPath = $scope.fileNavigator.currentPath; + }; - $scope.setTemplate = function(name) { - $storage.setItem('viewTemplate', name); - $scope.viewTemplate = name; - }; + $scope.setTemplate = function(name) { + $storage.setItem('viewTemplate', name); + $scope.viewTemplate = name; + }; - $scope.changeLanguage = function (locale) { - if (locale) { - $storage.setItem('language', locale); - return $translate.use(locale); - } - $translate.use($storage.getItem('language') || fileManagerConfig.defaultLang); - }; + $scope.changeLanguage = function (locale) { + if (locale) { + $storage.setItem('language', locale); + return $translate.use(locale); + } + $translate.use($storage.getItem('language') || fileManagerConfig.defaultLang); + }; - $scope.isSelected = function(item) { - return $scope.temps.indexOf(item) !== -1; - }; + $scope.isSelected = function(item) { + return $scope.temps.indexOf(item) !== -1; + }; - $scope.selectOrUnselect = function(item, $event) { - var indexInTemp = $scope.temps.indexOf(item); - var isRightClick = $event && $event.which == 3; + $scope.selectOrUnselect = function(item, $event) { + var indexInTemp = $scope.temps.indexOf(item); + var isRightClick = $event && $event.which == 3; - if ($event && $event.target.hasAttribute('prevent')) { + if ($event && $event.target.hasAttribute('prevent')) { + $scope.temps = []; + return; + } + if (! item || (isRightClick && $scope.isSelected(item))) { + return; + } + if ($event && $event.shiftKey && !isRightClick) { + var list = $scope.fileList; + var indexInList = list.indexOf(item); + var lastSelected = $scope.temps[0]; + var i = list.indexOf(lastSelected); + var current = undefined; + if (lastSelected && list.indexOf(lastSelected) < indexInList) { $scope.temps = []; + while (i <= indexInList) { + current = list[i]; + !$scope.isSelected(current) && $scope.temps.push(current); + i++; + } return; } - if (! item || (isRightClick && $scope.isSelected(item))) { - return; - } - if ($event && $event.shiftKey && !isRightClick) { - var list = $scope.fileList; - var indexInList = list.indexOf(item); - var lastSelected = $scope.temps[0]; - var i = list.indexOf(lastSelected); - var current = undefined; - if (lastSelected && list.indexOf(lastSelected) < indexInList) { - $scope.temps = []; - while (i <= indexInList) { - current = list[i]; - !$scope.isSelected(current) && $scope.temps.push(current); - i++; - } - return; - } - if (lastSelected && list.indexOf(lastSelected) > indexInList) { - $scope.temps = []; - while (i >= indexInList) { - current = list[i]; - !$scope.isSelected(current) && $scope.temps.push(current); - i--; - } - return; + if (lastSelected && list.indexOf(lastSelected) > indexInList) { + $scope.temps = []; + while (i >= indexInList) { + current = list[i]; + !$scope.isSelected(current) && $scope.temps.push(current); + i--; } - } - if ($event && !isRightClick && ($event.ctrlKey || $event.metaKey)) { - $scope.isSelected(item) ? $scope.temps.splice(indexInTemp, 1) : $scope.temps.push(item); return; } - $scope.temps = [item]; - }; - - $scope.singleSelection = function() { - return $scope.temps.length === 1 && $scope.temps[0]; - }; + } + if ($event && !isRightClick && ($event.ctrlKey || $event.metaKey)) { + $scope.isSelected(item) ? $scope.temps.splice(indexInTemp, 1) : $scope.temps.push(item); + return; + } + $scope.temps = [item]; + }; - $scope.totalSelecteds = function() { - return { - total: $scope.temps.length - }; - }; + $scope.singleSelection = function() { + return $scope.temps.length === 1 && $scope.temps[0]; + }; - $scope.selectionHas = function(type) { - return $scope.temps.find(function(item) { - return item && item.model.type === type; - }); + $scope.totalSelecteds = function() { + return { + total: $scope.temps.length }; + }; - $scope.prepareNewFolder = function() { - var item = new Item(null, $scope.fileNavigator.currentPath); - $scope.temps = [item]; - return item; - }; + $scope.selectionHas = function(type) { + return $scope.temps.find(function(item) { + return item && item.model.type === type; + }); + }; - $scope.smartClick = function(item) { - var pick = $scope.config.allowedActions.pickFiles; - if (item.isFolder()) { - return $scope.fileNavigator.folderClick(item); - } + $scope.prepareNewFolder = function() { + var item = new Item(null, $scope.fileNavigator.currentPath); + $scope.temps = [item]; + return item; + }; - if (typeof $scope.config.pickCallback === 'function' && pick) { - var callbackSuccess = $scope.config.pickCallback(item.model); - if (callbackSuccess === true) { - return; - } - } + $scope.smartClick = function(item) { + var pick = $scope.config.allowedActions.pickFiles; + if (item.isFolder()) { + return $scope.fileNavigator.folderClick(item); + } - if (item.isImage()) { - if ($scope.config.previewImagesInModal) { - return $scope.openImagePreview(item); - } - return $scope.apiMiddleware.download(item, true); + if (typeof $scope.config.pickCallback === 'function' && pick) { + var callbackSuccess = $scope.config.pickCallback(item.model); + if (callbackSuccess === true) { + return; } + } - if (item.isEditable()) { - return $scope.openEditItem(item); + if (item.isImage()) { + if ($scope.config.previewImagesInModal) { + return $scope.openImagePreview(item); } - }; + return $scope.apiMiddleware.download(item, true); + } - $scope.openImagePreview = function() { - var item = $scope.singleSelection(); - $scope.apiMiddleware.apiHandler.inprocess = true; - $scope.modal('imagepreview', null, true) - .find('#imagepreview-target') - .attr('src', $scope.apiMiddleware.getUrl(item)) - .unbind('load error') - .on('load error', function() { - $scope.apiMiddleware.apiHandler.inprocess = false; - $scope.$apply(); - }); - }; + if (item.isEditable()) { + return $scope.openEditItem(item); + } + }; - $scope.openEditItem = function() { - var item = $scope.singleSelection(); - $scope.apiMiddleware.getContent(item).then(function(data) { - item.tempModel.content = item.model.content = data.result; + $scope.openImagePreview = function() { + var item = $scope.singleSelection(); + $scope.apiMiddleware.apiHandler.inprocess = true; + $scope.modal('imagepreview', null, true) + .find('#imagepreview-target') + .attr('src', $scope.apiMiddleware.getUrl(item)) + .unbind('load error') + .on('load error', function() { + $scope.apiMiddleware.apiHandler.inprocess = false; + $scope.$apply(); }); - $scope.modal('edit'); - }; + }; - $scope.modal = function(id, hide, returnElement) { - var element = $('#' + id); - element.modal(hide ? 'hide' : 'show'); - $scope.apiMiddleware.apiHandler.error = ''; - $scope.apiMiddleware.apiHandler.asyncSuccess = false; - return returnElement ? element : true; - }; + $scope.openEditItem = function() { + var item = $scope.singleSelection(); + $scope.apiMiddleware.getContent(item).then(function(data) { + item.tempModel.content = item.model.content = data.result; + }); + $scope.modal('edit'); + }; - $scope.modalWithPathSelector = function(id) { - $rootScope.selectedModalPath = $scope.fileNavigator.currentPath; - return $scope.modal(id); - }; + $scope.modal = function(id, hide, returnElement) { + var element = $('#' + id); + element.modal(hide ? 'hide' : 'show'); + $scope.apiMiddleware.apiHandler.error = ''; + $scope.apiMiddleware.apiHandler.asyncSuccess = false; + return returnElement ? element : true; + }; - $scope.isInThisPath = function(path) { - var currentPath = $scope.fileNavigator.currentPath.join('/'); - return currentPath.indexOf(path) !== -1; - }; + $scope.modalWithPathSelector = function(id) { + $rootScope.selectedModalPath = $scope.fileNavigator.currentPath; + return $scope.modal(id); + }; - $scope.edit = function() { - $scope.apiMiddleware.edit($scope.singleSelection()).then(function() { - $scope.modal('edit', true); - }); + $scope.isInThisPath = function(path) { + var currentPath = $scope.fileNavigator.currentPath.join('/'); + return currentPath.indexOf(path) !== -1; + }; + + $scope.edit = function() { + $scope.apiMiddleware.edit($scope.singleSelection()).then(function() { + $scope.modal('edit', true); + }); + }; + + $scope.updatePermissions = function () { + var item = $scope.singleSelection(); + var apiUrl = fileManagerConfig.permissionsUrl; + var data = { + action: 'resolvePermissions', + path: item.model.fullPath() }; - $scope.updatePermissions = function () { - var item = $scope.singleSelection(); - var apiUrl = fileManagerConfig.permissionsUrl; - var data = { - action: 'resolvePermissions', - path: item.model.fullPath() - }; - - $http.post(apiUrl, data) - .success(function (data) { - item.model.authRead = data.auth.read; - item.model.authUpdate = data.auth.update; - item.model.authDelete = data.auth.delete; - }).error(function () { + $http.post(apiUrl, data) + .success(function (data) { + item.model.authRead = data.auth.read; + item.model.authUpdate = data.auth.update; + item.model.authDelete = data.auth.delete; + }).error(function () { $scope.apiMiddleware.apiHandler.error = $translate.instant('error_get_permissions'); })['finally'](function () { - $scope.modal('changepermissions', false); - }); - }; - $scope.changePermissions = function() { - var item = $scope.singleSelection(); - $scope.apiMiddleware.changePermissions(item.tempModel).then(function() { - $scope.modal('changepermissions', true); - }); - }; - - $scope.rename = function() { - var item = $scope.singleSelection(); - var name = item.tempModel.name; - var samePath = item.tempModel.path.join('') === item.model.path.join(''); - if (!name || (samePath && $scope.fileNavigator.fileNameExists(name))) { - $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); - return false; - } - $scope.apiMiddleware.rename(item).then(function() { - $scope.fileNavigator.refresh(); - $scope.modal('rename', true); - }); - }; + $scope.modal('changepermissions', false); + }); + }; + $scope.changePermissions = function() { + var item = $scope.singleSelection(); + $scope.apiMiddleware.changePermissions(item.tempModel).then(function() { + $scope.modal('changepermissions', true); + }); + }; - $scope.refreshLocation = function(recycle) { - $scope.fileNavigator.refresh(recycle); - }; + $scope.rename = function() { + var item = $scope.singleSelection(); + var name = item.tempModel.name; + var samePath = item.tempModel.path.join('') === item.model.path.join(''); + if (!name || (samePath && $scope.fileNavigator.fileNameExists(name))) { + $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); + return false; + } + $scope.apiMiddleware.rename(item).then(function() { + $scope.fileNavigator.refresh(); + $scope.modal('rename', true); + }); + }; - $scope.downloadLink = function() { - var item = $scope.singleSelection(); - if ($scope.selectionHas('dir')) { - return; - } + $scope.refreshLocation = function(recycle) { + $scope.fileNavigator.refresh(recycle); + }; - var itemFullPath = item.model.fullPath(); + $scope.downloadLink = function() { + var item = $scope.singleSelection(); + if ($scope.selectionHas('dir')) { + return; + } - // generate download url - var downloadData = { - action: 'download', - path: itemFullPath - }; + var itemFullPath = item.model.fullPath(); - // generate stream url - var streamData = { - action: 'stream', - path: itemFullPath - }; + // generate download url + var downloadData = { + action: 'download', + path: itemFullPath + }; - var domain = window.location.protocol + '//' + window.location.host; - var downloadPath = [fileManagerConfig.downloadFileUrl, $.param(downloadData)].join('?'); - var streamPath = [fileManagerConfig.downloadFileUrl, $.param(streamData)].join('?'); + // generate stream url + var streamData = { + action: 'stream', + path: itemFullPath + }; - $scope.dlLink = domain + downloadPath; - $scope.streamLink = streamPath; - $scope.path = itemFullPath; + var domain = window.location.protocol + '//' + window.location.host; + var downloadPath = [fileManagerConfig.downloadFileUrl, $.param(downloadData)].join('?'); + var streamPath = [fileManagerConfig.downloadFileUrl, $.param(streamData)].join('?'); - //open modal - $scope.modal('downloadlink', false); - }; + $scope.dlLink = domain + downloadPath; + $scope.streamLink = streamPath; + $scope.path = itemFullPath; - $scope.download = function() { - var item = $scope.singleSelection(); - if ($scope.selectionHas('dir')) { - return; - } - if (item) { - return $scope.apiMiddleware.download(item); - } - return $scope.apiMiddleware.downloadMultiple($scope.temps); - }; + //open modal + $scope.modal('downloadlink', false); + }; - $scope.copy = function() { - var item = $scope.singleSelection(); - if (item) { - var name = item.tempModel.name.trim(); - var nameExists = $scope.fileNavigator.fileNameExists(name); - if (nameExists && validateSamePath(item)) { - $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); - return false; - } - if (!name) { - $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); - return false; - } - } - $scope.apiMiddleware.copy($scope.temps, $rootScope.selectedModalPath).then(function() { - $scope.fileNavigator.refresh(); - $scope.modal('copy', true); - }); - }; + $scope.download = function() { + var item = $scope.singleSelection(); + if ($scope.selectionHas('dir')) { + return; + } + if (item) { + return $scope.apiMiddleware.download(item); + } + return $scope.apiMiddleware.downloadMultiple($scope.temps); + }; - $scope.compress = function() { - var name = $scope.temp.tempModel.name.trim(); + $scope.copy = function() { + var item = $scope.singleSelection(); + if (item) { + var name = item.tempModel.name.trim(); var nameExists = $scope.fileNavigator.fileNameExists(name); - - if (nameExists && validateSamePath($scope.temp)) { + if (nameExists && validateSamePath(item)) { $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); return false; } @@ -368,172 +349,232 @@ $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); return false; } + } + $scope.apiMiddleware.copy($scope.temps, $rootScope.selectedModalPath).then(function() { + $scope.fileNavigator.refresh(); + $scope.modal('copy', true); + }); + }; - $scope.apiMiddleware.compress($scope.temps, name, $rootScope.selectedModalPath).then(function() { - $scope.fileNavigator.refresh(); - if (! $scope.config.compressAsync) { - return $scope.modal('compress', true); - } - $scope.apiMiddleware.apiHandler.asyncSuccess = true; - }, function() { - $scope.apiMiddleware.apiHandler.asyncSuccess = false; - }); - }; + $scope.compress = function() { + var name = $scope.temp.tempModel.name.trim(); + var nameExists = $scope.fileNavigator.fileNameExists(name); - $scope.extract = function() { - var item = $scope.temp; - var name = $scope.temp.tempModel.name.trim(); - var nameExists = $scope.fileNavigator.fileNameExists(name); + if (nameExists && validateSamePath($scope.temp)) { + $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); + return false; + } + if (!name) { + $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); + return false; + } - if (nameExists && validateSamePath($scope.temp)) { - $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); - return false; - } - if (!name) { - $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); - return false; + $scope.apiMiddleware.compress($scope.temps, name, $rootScope.selectedModalPath).then(function() { + $scope.fileNavigator.refresh(); + if (! $scope.config.compressAsync) { + return $scope.modal('compress', true); } + $scope.apiMiddleware.apiHandler.asyncSuccess = true; + }, function() { + $scope.apiMiddleware.apiHandler.asyncSuccess = false; + }); + }; - $scope.apiMiddleware.extract(item, name, $rootScope.selectedModalPath).then(function() { - $scope.fileNavigator.refresh(); - if (! $scope.config.extractAsync) { - return $scope.modal('extract', true); - } - $scope.apiMiddleware.apiHandler.asyncSuccess = true; - }, function() { - $scope.apiMiddleware.apiHandler.asyncSuccess = false; - }); - }; + $scope.extract = function() { + var item = $scope.temp; + var name = $scope.temp.tempModel.name.trim(); + var nameExists = $scope.fileNavigator.fileNameExists(name); - $scope.remove = function() { - $scope.apiMiddleware.remove($scope.temps).then(function() { - $scope.fileNavigator.refresh(); - $scope.modal('remove', true); - }); - }; + if (nameExists && validateSamePath($scope.temp)) { + $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); + return false; + } + if (!name) { + $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); + return false; + } - $scope.move = function() { - var anyItem = $scope.singleSelection() || $scope.temps[0]; - if (anyItem && validateSamePath(anyItem)) { - $scope.apiMiddleware.apiHandler.error = $translate.instant('error_cannot_move_same_path'); - return false; + $scope.apiMiddleware.extract(item, name, $rootScope.selectedModalPath).then(function() { + $scope.fileNavigator.refresh(); + if (! $scope.config.extractAsync) { + return $scope.modal('extract', true); } - $scope.apiMiddleware.move($scope.temps, $rootScope.selectedModalPath).then(function() { - $scope.fileNavigator.refresh(); - $scope.modal('move', true); - }); - }; + $scope.apiMiddleware.apiHandler.asyncSuccess = true; + }, function() { + $scope.apiMiddleware.apiHandler.asyncSuccess = false; + }); + }; - $scope.createFolder = function() { - var item = $scope.singleSelection(); - var name = item.tempModel.name; - if (!name || $scope.fileNavigator.fileNameExists(name)) { - return $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); - } - $scope.apiMiddleware.createFolder(item).then(function() { - $scope.fileNavigator.refresh(); - $scope.modal('newfolder', true); - }); - }; + $scope.remove = function() { + $scope.apiMiddleware.remove($scope.temps).then(function() { + $scope.fileNavigator.refresh(); + $scope.modal('remove', true); + }); + }; - $scope.addForUpload = function($files) { - $scope.uploadFileList = $scope.uploadFileList.concat($files); - $scope.modal('uploadfile'); - }; + $scope.move = function() { + var anyItem = $scope.singleSelection() || $scope.temps[0]; + if (anyItem && validateSamePath(anyItem)) { + $scope.apiMiddleware.apiHandler.error = $translate.instant('error_cannot_move_same_path'); + return false; + } + $scope.apiMiddleware.move($scope.temps, $rootScope.selectedModalPath).then(function() { + $scope.fileNavigator.refresh(); + $scope.modal('move', true); + }); + }; - $scope.removeFromUpload = function(index) { - $scope.uploadFileList.splice(index, 1); - }; + $scope.createFolder = function() { + var item = $scope.singleSelection(); + var name = item.tempModel.name; + if (!name || $scope.fileNavigator.fileNameExists(name)) { + return $scope.apiMiddleware.apiHandler.error = $translate.instant('error_invalid_filename'); + } + $scope.apiMiddleware.createFolder(item).then(function() { + $scope.fileNavigator.refresh(); + $scope.modal('newfolder', true); + }); + }; - $scope.uploadFiles = function() { - $scope.apiMiddleware.upload($scope.uploadFileList, $scope.fileNavigator.currentPath).then(function() { - $scope.fileNavigator.refresh(); - $scope.uploadFileList = []; - $scope.modal('uploadfile', true); - }, function(data) { - var errorMsg = data.result && data.result.error || $translate.instant('error_uploading_files'); - $scope.apiMiddleware.apiHandler.error = errorMsg; - }); - }; + $scope.addForUpload = function($files) { + $scope.uploadFileList = $scope.uploadFileList.concat($files); + $scope.modal('uploadfile'); + }; - var validateSamePath = function(item) { - var selectedPath = $rootScope.selectedModalPath.join(''); - var selectedItemsPath = item && item.model.path.join(''); - return selectedItemsPath === selectedPath; - }; + $scope.removeFromUpload = function(index) { + $scope.uploadFileList.splice(index, 1); + }; - var getQueryParam = function(param) { - var found = $window.location.search.substr(1).split('&').filter(function(item) { - return param === item.split('=')[0]; - }); - return found[0] && found[0].split('=')[1] || undefined; - }; + $scope.uploadFiles = function() { + $scope.apiMiddleware.upload($scope.uploadFileList, $scope.fileNavigator.currentPath).then(function() { + $scope.fileNavigator.refresh(); + $scope.uploadFileList = []; + $scope.modal('uploadfile', true); + }, function(data) { + var errorMsg = data.result && data.result.error || $translate.instant('error_uploading_files'); + $scope.apiMiddleware.apiHandler.error = errorMsg; + }); + }; - $scope.changeLanguage(getQueryParam('lang')); - $scope.isWindows = getQueryParam('server') === 'Windows'; - $scope.fileNavigator.refresh(); + var validateSamePath = function(item) { + var selectedPath = $rootScope.selectedModalPath.join(''); + var selectedItemsPath = item && item.model.path.join(''); + return selectedItemsPath === selectedPath; + }; + + var getQueryParam = function(param) { + var found = $window.location.search.substr(1).split('&').filter(function(item) { + return param === item.split('=')[0]; + }); + return found[0] && found[0].split('=')[1] || undefined; + }; + + $scope.changeLanguage(getQueryParam('lang')); + $scope.isWindows = getQueryParam('server') === 'Windows'; + $scope.fileNavigator.refresh(); - }]); + }]); })(angular, jQuery); (function(angular) { 'use strict'; - angular.module('FileManagerApp').controller('ModalFileManagerCtrl', + angular.module('FileManagerApp').controller('ModalFileManagerCtrl', ['$scope', '$rootScope', 'fileNavigator', function($scope, $rootScope, FileNavigator) { - $scope.reverse = false; - $scope.predicate = ['model.type', 'model.name']; - $scope.fileNavigator = new FileNavigator(); - $rootScope.selectedModalPath = []; + $scope.reverse = false; + $scope.predicate = ['model.type', 'model.name']; + $scope.fileNavigator = new FileNavigator(); + $rootScope.selectedModalPath = []; - $scope.order = function(predicate) { - $scope.reverse = ($scope.predicate[1] === predicate) ? !$scope.reverse : false; - $scope.predicate[1] = predicate; - }; + $scope.order = function(predicate) { + $scope.reverse = ($scope.predicate[1] === predicate) ? !$scope.reverse : false; + $scope.predicate[1] = predicate; + }; - $scope.select = function(item) { - $rootScope.selectedModalPath = item.model.fullPath().split('/'); - $scope.modal('selector', true); - }; + $scope.select = function(item) { + $rootScope.selectedModalPath = item.model.fullPath().split('/'); + $scope.modal('selector', true); + }; - $scope.selectCurrent = function() { - $rootScope.selectedModalPath = $scope.fileNavigator.currentPath; - $scope.modal('selector', true); - }; + $scope.selectCurrent = function() { + $rootScope.selectedModalPath = $scope.fileNavigator.currentPath; + $scope.modal('selector', true); + }; - $scope.selectedFilesAreChildOfPath = function(item) { - var path = item.model.fullPath(); - return $scope.temps.find(function(item) { - var itemPath = item.model.fullPath(); - if (path == itemPath) { - return true; - } - /* - if (path.startsWith(itemPath)) { - fixme names in same folder like folder-one and folder-one-two - at the moment fixed hidding affected folders - } - */ - }); - }; + $scope.selectedFilesAreChildOfPath = function(item) { + var path = item.model.fullPath(); + return $scope.temps.find(function(item) { + var itemPath = item.model.fullPath(); + if (path == itemPath) { + return true; + } + /* + if (path.startsWith(itemPath)) { + fixme names in same folder like folder-one and folder-one-two + at the moment fixed hidding affected folders + } + */ + }); + }; - $rootScope.openNavigator = function(path) { - $scope.fileNavigator.currentPath = path; - $scope.fileNavigator.refresh(); - $scope.modal('selector'); - }; + $rootScope.openNavigator = function(path) { + $scope.fileNavigator.currentPath = path; + $scope.fileNavigator.refresh(); + $scope.modal('selector'); + }; - $rootScope.getSelectedPath = function() { - var path = $rootScope.selectedModalPath.filter(Boolean); - var result = '/' + path.join('/'); - if ($scope.singleSelection() && !$scope.singleSelection().isFolder()) { - result += '/' + $scope.singleSelection().tempModel.name; - } - return result.replace(/\/\//, '/'); - }; + $rootScope.getSelectedPath = function() { + var path = $rootScope.selectedModalPath.filter(Boolean); + var result = '/' + path.join('/'); + if ($scope.singleSelection() && !$scope.singleSelection().isFolder()) { + result += '/' + $scope.singleSelection().tempModel.name; + } + return result.replace(/\/\//, '/'); + }; + + }]); +})(angular); +(function(angular) { + 'use strict'; + var app = angular.module('FileManagerApp'); + + app.directive('angularFilemanager', ['$parse', 'fileManagerConfig', function($parse, fileManagerConfig) { + return { + restrict: 'EA', + templateUrl: fileManagerConfig.tplPath + '/main.html' + }; + }]); + + app.directive('ngFile', ['$parse', function($parse) { + return { + restrict: 'A', + link: function(scope, element, attrs) { + var model = $parse(attrs.ngFile); + var modelSetter = model.assign; + + element.bind('change', function() { + scope.$apply(function() { + modelSetter(scope, element[0].files); + }); + }); + } + }; + }]); - }]); + app.directive('ngRightClick', ['$parse', function($parse) { + return function(scope, element, attrs) { + var fn = $parse(attrs.ngRightClick); + element.bind('contextmenu', function(event) { + scope.$apply(function() { + event.preventDefault(); + fn(scope, {$event: event}); + }); + }); + }; + }]); + })(angular); + (function(angular) { 'use strict'; angular.module('FileManagerApp').service('chmod', function () { @@ -650,6 +691,7 @@ var Item = function(model, path) { var rawModel = { name: model && model.name || '', + thumbnail: model && model.thumbnail || '', path: path || [], type: model && model.type || 'file', size: model && parseInt(model.size || 0), @@ -711,47 +753,6 @@ return Item; }]); })(angular); -(function(angular) { - 'use strict'; - var app = angular.module('FileManagerApp'); - - app.directive('angularFilemanager', ['$parse', 'fileManagerConfig', function($parse, fileManagerConfig) { - return { - restrict: 'EA', - templateUrl: fileManagerConfig.tplPath + '/main.html' - }; - }]); - - app.directive('ngFile', ['$parse', function($parse) { - return { - restrict: 'A', - link: function(scope, element, attrs) { - var model = $parse(attrs.ngFile); - var modelSetter = model.assign; - - element.bind('change', function() { - scope.$apply(function() { - modelSetter(scope, element[0].files); - }); - }); - } - }; - }]); - - app.directive('ngRightClick', ['$parse', function($parse) { - return function(scope, element, attrs) { - var fn = $parse(attrs.ngRightClick); - element.bind('contextmenu', function(event) { - scope.$apply(function() { - event.preventDefault(); - fn(scope, {$event: event}); - }); - }); - }; - }]); - -})(angular); - (function(angular) { 'use strict'; var app = angular.module('FileManagerApp'); @@ -780,22 +781,22 @@ }]); app.filter('humanReadableFileSize', ['$filter', 'fileManagerConfig', function($filter, fileManagerConfig) { - // See https://en.wikipedia.org/wiki/Binary_prefix - var decimalByteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB']; - var binaryByteUnits = ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; - - return function(input) { - var i = -1; - var fileSizeInBytes = input; - - do { - fileSizeInBytes = fileSizeInBytes / 1024; - i++; - } while (fileSizeInBytes > 1024); - - var result = fileManagerConfig.useBinarySizePrefixes ? binaryByteUnits[i] : decimalByteUnits[i]; - return Math.max(fileSizeInBytes, 0.1).toFixed(1) + ' ' + result; - }; + // See https://en.wikipedia.org/wiki/Binary_prefix + var decimalByteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB']; + var binaryByteUnits = ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + + return function(input) { + var i = -1; + var fileSizeInBytes = input; + + do { + fileSizeInBytes = fileSizeInBytes / 1024; + i++; + } while (fileSizeInBytes > 1024); + + var result = fileManagerConfig.useBinarySizePrefixes ? binaryByteUnits[i] : decimalByteUnits[i]; + return Math.max(fileSizeInBytes, 0.1).toFixed(1) + ' ' + result; + }; }]); })(angular); @@ -855,6 +856,10 @@ compressAsync: false, extractAsync: false, pickCallback: null, + thumbnailUrlPrefix: '', + thumbnailUrlSuffix: '', + enableThumbnails: true, + enableIconPreviewView: false, isEditableFilePattern: /\.(txt|diff?|patch|svg|asc|cnf|cfg|conf|html?|.html|cfm|cgi|aspx?|ini|pl|py|md|css|cs|js|jsp|log|htaccess|htpasswd|gitignore|gitattributes|env|json|atom|eml|rss|markdown|sql|xml|xslt?|sh|rb|as|bat|cmd|cob|for|ftn|frm|frx|inc|lisp|scm|coffee|php[3-6]?|java|c|cbl|go|h|scala|vb|tmpl|lock|go|yml|yaml|tsv|lst)$/i, isImageFilePattern: /\.(jpe?g|gif|bmp|png|svg|tiff?)$/i, @@ -2040,683 +2045,691 @@ angular.module('FileManagerApp').service('apiHandler', ['$http', '$q', '$window', '$translate', 'Upload', function ($http, $q, $window, $translate, Upload) { - $http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; - - var ApiHandler = function() { - this.inprocess = false; - this.asyncSuccess = false; - this.error = ''; - }; - - ApiHandler.prototype.deferredHandler = function(data, deferred, code, defaultMsg) { - if (!data || typeof data !== 'object') { - this.error = 'Error %s - Bridge response error, please check the API docs or this ajax response.'.replace('%s', code); - } - if (code == 404) { - this.error = 'Error 404 - Backend bridge is not working, please check the ajax response.'; - } - if (data.result && data.result.error) { - this.error = data.result.error; - } - if (!this.error && data.error) { - this.error = data.error.message; - } - if (!this.error && defaultMsg) { - this.error = defaultMsg; - } - if (this.error) { - return deferred.reject(data); - } - return deferred.resolve(data); - }; - - ApiHandler.prototype.list = function(apiUrl, path, customDeferredHandler, recycle) { - var self = this; - var dfHandler = customDeferredHandler || self.deferredHandler; - var deferred = $q.defer(); - var data = { - action: 'list', - path: path, - recycle: recycle - }; - - self.inprocess = true; - self.error = ''; - - $http.post(apiUrl, data).success(function(data, code) { - dfHandler(data, deferred, code); - }).error(function(data, code) { - dfHandler(data, deferred, code, 'Unknown error listing, check the response'); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; - }; + $http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; - ApiHandler.prototype.copy = function(apiUrl, items, path, singleFilename) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'copy', - items: items, - newPath: path - }; - - if (singleFilename && items.length === 1) { - data.singleFilename = singleFilename; - } + var ApiHandler = function() { + this.inprocess = false; + this.asyncSuccess = false; + this.error = ''; + }; - self.inprocess = true; - self.error = ''; - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_copying')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; - }; + ApiHandler.prototype.deferredHandler = function(data, deferred, code, defaultMsg) { + if (!data || typeof data !== 'object') { + this.error = 'Error %s - Bridge response error, please check the API docs or this ajax response.'.replace('%s', code); + } + if (code == 404) { + this.error = 'Error 404 - Backend bridge is not working, please check the ajax response.'; + } + if (data.result && data.result.error) { + this.error = data.result.error; + } + if (!this.error && data.error) { + this.error = data.error.message; + } + if (!this.error && defaultMsg) { + this.error = defaultMsg; + } + if (this.error) { + return deferred.reject(data); + } + return deferred.resolve(data); + }; - ApiHandler.prototype.move = function(apiUrl, items, path) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'move', - items: items, - newPath: path - }; - self.inprocess = true; - self.error = ''; - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_moving')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; - }; + ApiHandler.prototype.list = function(apiUrl, path, customDeferredHandler, recycle) { + var self = this; + var dfHandler = customDeferredHandler || self.deferredHandler; + var deferred = $q.defer(); + var data = { + action: 'list', + path: path, + recycle: recycle + }; + + self.inprocess = true; + self.error = ''; + + $http.post(apiUrl, data).success(function(data, code) { + dfHandler(data, deferred, code); + }).error(function(data, code) { + dfHandler(data, deferred, code, 'Unknown error listing, check the response'); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; - ApiHandler.prototype.remove = function(apiUrl, items) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'remove', - items: items - }; - - self.inprocess = true; - self.error = ''; - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_deleting')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; + ApiHandler.prototype.copy = function(apiUrl, items, path, singleFilename) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'copy', + items: items, + newPath: path }; - ApiHandler.prototype.upload = function(apiUrl, destination, files) { - var self = this; - var deferred = $q.defer(); - self.inprocess = true; - self.progress = 0; - self.error = ''; + if (singleFilename && items.length === 1) { + data.singleFilename = singleFilename; + } + + self.inprocess = true; + self.error = ''; + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_copying')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; - var data = { - destination: destination - }; + ApiHandler.prototype.move = function(apiUrl, items, path) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'move', + items: items, + newPath: path + }; + self.inprocess = true; + self.error = ''; + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_moving')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; - for (var i = 0; i < files.length; i++) { - data['file-' + i] = files[i]; - } + ApiHandler.prototype.remove = function(apiUrl, items) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'remove', + items: items + }; + + self.inprocess = true; + self.error = ''; + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_deleting')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; - if (files && files.length) { - Upload.upload({ - url: apiUrl, - data: data - }).then(function (data) { - self.deferredHandler(data.data, deferred, data.status); - }, function (data) { - self.deferredHandler(data.data, deferred, data.status, 'Unknown error uploading files'); - }, function (evt) { - self.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total)) - 1; - })['finally'](function() { - self.inprocess = false; - self.progress = 0; - }); - } + ApiHandler.prototype.upload = function(apiUrl, destination, files) { + var self = this; + var deferred = $q.defer(); + self.inprocess = true; + self.progress = 0; + self.error = ''; - return deferred.promise; + var data = { + destination: destination }; - ApiHandler.prototype.getContent = function(apiUrl, itemPath) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'getContent', - item: itemPath - }; - - self.inprocess = true; - self.error = ''; - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_getting_content')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; - }; + for (var i = 0; i < files.length; i++) { + data['file-' + i] = files[i]; + } - ApiHandler.prototype.edit = function(apiUrl, itemPath, content) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'edit', - item: itemPath, - content: content - }; - - self.inprocess = true; - self.error = ''; - - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_modifying')); + if (files && files.length) { + Upload.upload({ + url: apiUrl, + data: data + }).then(function (data) { + self.deferredHandler(data.data, deferred, data.status); + }, function (data) { + self.deferredHandler(data.data, deferred, data.status, 'Unknown error uploading files'); + }, function (evt) { + self.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total)) - 1; })['finally'](function() { self.inprocess = false; + self.progress = 0; }); - return deferred.promise; - }; + } - ApiHandler.prototype.rename = function(apiUrl, itemPath, newPath) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'rename', - item: itemPath, - newItemPath: newPath - }; - self.inprocess = true; - self.error = ''; - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_renaming')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; - }; + return deferred.promise; + }; - ApiHandler.prototype.getUrl = function(apiUrl, path) { - var data = { - action: 'download', - path: path - }; - return path && [apiUrl, $.param(data)].join('?'); + ApiHandler.prototype.getContent = function(apiUrl, itemPath) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'getContent', + item: itemPath + }; + + self.inprocess = true; + self.error = ''; + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_getting_content')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; + + ApiHandler.prototype.edit = function(apiUrl, itemPath, content) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'edit', + item: itemPath, + content: content }; - ApiHandler.prototype.download = function(apiUrl, itemPath, toFilename, downloadByAjax, forceNewWindow) { - var self = this; - var url = this.getUrl(apiUrl, itemPath); + self.inprocess = true; + self.error = ''; - if (!downloadByAjax || forceNewWindow || !$window.saveAs) { - !$window.saveAs && $window.console.log('Your browser dont support ajax download, downloading by default'); - return !!$window.open(url, '_blank', ''); - } + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_modifying')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; - var deferred = $q.defer(); - self.inprocess = true; - $http.get(url).success(function(data) { - var bin = new $window.Blob([data]); - deferred.resolve(data); - $window.saveAs(bin, toFilename); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_downloading')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; + ApiHandler.prototype.rename = function(apiUrl, itemPath, newPath) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'rename', + item: itemPath, + newItemPath: newPath + }; + self.inprocess = true; + self.error = ''; + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_renaming')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; + + ApiHandler.prototype.getUrl = function(apiUrl, path) { + var data = { + action: 'download', + path: path }; + return path && [apiUrl, $.param(data)].join('?'); + }; - ApiHandler.prototype.downloadMultiple = function(apiUrl, items, toFilename, downloadByAjax, forceNewWindow) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'downloadMultiple', - items: items, - toFilename: toFilename - }; - var url = [apiUrl, $.param(data)].join('?'); - - if (!downloadByAjax || forceNewWindow || !$window.saveAs) { - !$window.saveAs && $window.console.log('Your browser dont support ajax download, downloading by default'); - return !!$window.open(url, '_blank', ''); - } + ApiHandler.prototype.download = function(apiUrl, itemPath, toFilename, downloadByAjax, forceNewWindow) { + var self = this; + var url = this.getUrl(apiUrl, itemPath); - self.inprocess = true; - $http.get(apiUrl).success(function(data) { - var bin = new $window.Blob([data]); - deferred.resolve(data); - $window.saveAs(bin, toFilename); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_downloading')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; - }; + if (!downloadByAjax || forceNewWindow || !$window.saveAs) { + !$window.saveAs && $window.console.log('Your browser dont support ajax download, downloading by default'); + return !!$window.open(url, '_blank', ''); + } + + var deferred = $q.defer(); + self.inprocess = true; + $http.get(url).success(function(data) { + var bin = new $window.Blob([data]); + deferred.resolve(data); + $window.saveAs(bin, toFilename); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_downloading')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; - ApiHandler.prototype.compress = function(apiUrl, items, compressedFilename, path) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'compress', - items: items, - destination: path, - compressedFilename: compressedFilename - }; - - self.inprocess = true; - self.error = ''; - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_compressing')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; + ApiHandler.prototype.downloadMultiple = function(apiUrl, items, toFilename, downloadByAjax, forceNewWindow) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'downloadMultiple', + items: items, + toFilename: toFilename }; + var url = [apiUrl, $.param(data)].join('?'); - ApiHandler.prototype.extract = function(apiUrl, item, folderName, path) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'extract', - item: item, - destination: path, - folderName: folderName - }; - - self.inprocess = true; - self.error = ''; - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_extracting')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; - }; + if (!downloadByAjax || forceNewWindow || !$window.saveAs) { + !$window.saveAs && $window.console.log('Your browser dont support ajax download, downloading by default'); + return !!$window.open(url, '_blank', ''); + } + + self.inprocess = true; + $http.get(apiUrl).success(function(data) { + var bin = new $window.Blob([data]); + deferred.resolve(data); + $window.saveAs(bin, toFilename); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_downloading')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; + + ApiHandler.prototype.compress = function(apiUrl, items, compressedFilename, path) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'compress', + items: items, + destination: path, + compressedFilename: compressedFilename + }; + + self.inprocess = true; + self.error = ''; + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_compressing')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; - ApiHandler.prototype.changePermissions = function(apiUrl, item) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'changePermissions', - path: item.fullPath(), - item: item - }; - - self.inprocess = true; - self.error = ''; - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_changing_perms')); - })['finally'](function() { - self.inprocess = false; - }); - return deferred.promise; - }; + ApiHandler.prototype.extract = function(apiUrl, item, folderName, path) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'extract', + item: item, + destination: path, + folderName: folderName + }; + + self.inprocess = true; + self.error = ''; + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_extracting')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; - ApiHandler.prototype.createFolder = function(apiUrl, path) { - var self = this; - var deferred = $q.defer(); - var data = { - action: 'createFolder', - newPath: path - }; - - self.inprocess = true; - self.error = ''; - $http.post(apiUrl, data).success(function(data, code) { - self.deferredHandler(data, deferred, code); - }).error(function(data, code) { - self.deferredHandler(data, deferred, code, $translate.instant('error_creating_folder')); - })['finally'](function() { - self.inprocess = false; - }); + ApiHandler.prototype.changePermissions = function(apiUrl, item) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'changePermissions', + path: item.fullPath(), + item: item + }; + + self.inprocess = true; + self.error = ''; + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_changing_perms')); + })['finally'](function() { + self.inprocess = false; + }); + return deferred.promise; + }; - return deferred.promise; - }; + ApiHandler.prototype.createFolder = function(apiUrl, path) { + var self = this; + var deferred = $q.defer(); + var data = { + action: 'createFolder', + newPath: path + }; + + self.inprocess = true; + self.error = ''; + $http.post(apiUrl, data).success(function(data, code) { + self.deferredHandler(data, deferred, code); + }).error(function(data, code) { + self.deferredHandler(data, deferred, code, $translate.instant('error_creating_folder')); + })['finally'](function() { + self.inprocess = false; + }); + + return deferred.promise; + }; - ApiHandler.prototype.slug = function(str) { - var trimmed = $.trim(str); - var $slug = trimmed.replace(/[^a-z0-9-]/gi, '-'). + ApiHandler.prototype.slug = function(str) { + var trimmed = $.trim(str); + var $slug = trimmed.replace(/[^a-z0-9-]/gi, '-'). replace(/-+/g, '-'). replace(/^-|-$/g, ''); - return $slug.toLowerCase(); - }; + return $slug.toLowerCase(); + }; - return ApiHandler; + return ApiHandler; - }]); + }]); })(angular, jQuery); (function(angular) { 'use strict'; - angular.module('FileManagerApp').service('apiMiddleware', ['$window', 'fileManagerConfig', 'apiHandler', + angular.module('FileManagerApp').service('apiMiddleware', ['$window', 'fileManagerConfig', 'apiHandler', function ($window, fileManagerConfig, ApiHandler) { - var ApiMiddleware = function() { - this.apiHandler = new ApiHandler(); - }; + var ApiMiddleware = function() { + this.apiHandler = new ApiHandler(); + }; - ApiMiddleware.prototype.getPath = function(arrayPath) { - return '/' + arrayPath.join('/'); - }; + ApiMiddleware.prototype.getPath = function(arrayPath) { + return '/' + arrayPath.join('/'); + }; - ApiMiddleware.prototype.getFileList = function(files) { - return (files || []).map(function(file) { - return file && file.model.fullPath(); - }); - }; + ApiMiddleware.prototype.getFileList = function(files) { + return (files || []).map(function(file) { + return file && file.model.fullPath(); + }); + }; - ApiMiddleware.prototype.getFilePath = function(item) { - return item && item.model.fullPath(); - }; + ApiMiddleware.prototype.getFilePath = function(item) { + return item && item.model.fullPath(); + }; - ApiMiddleware.prototype.list = function(path, customDeferredHandler, recycle) { - return this.apiHandler.list(fileManagerConfig.listUrl, this.getPath(path), customDeferredHandler, recycle); - }; + ApiMiddleware.prototype.list = function(path, customDeferredHandler, recycle) { + return this.apiHandler.list(fileManagerConfig.listUrl, this.getPath(path), customDeferredHandler, recycle); + }; - ApiMiddleware.prototype.copy = function(files, path) { - var items = this.getFileList(files); - var singleFilename = items.length === 1 ? files[0].tempModel.name : undefined; - return this.apiHandler.copy(fileManagerConfig.copyUrl, items, this.getPath(path), singleFilename); - }; + ApiMiddleware.prototype.copy = function(files, path) { + var items = this.getFileList(files); + var singleFilename = items.length === 1 ? files[0].tempModel.name : undefined; + return this.apiHandler.copy(fileManagerConfig.copyUrl, items, this.getPath(path), singleFilename); + }; - ApiMiddleware.prototype.move = function(files, path) { - var items = this.getFileList(files); - return this.apiHandler.move(fileManagerConfig.moveUrl, items, this.getPath(path)); - }; + ApiMiddleware.prototype.move = function(files, path) { + var items = this.getFileList(files); + return this.apiHandler.move(fileManagerConfig.moveUrl, items, this.getPath(path)); + }; - ApiMiddleware.prototype.remove = function(files) { - var items = this.getFileList(files); - return this.apiHandler.remove(fileManagerConfig.removeUrl, items); - }; + ApiMiddleware.prototype.remove = function(files) { + var items = this.getFileList(files); + return this.apiHandler.remove(fileManagerConfig.removeUrl, items); + }; - ApiMiddleware.prototype.upload = function(files, path) { - if (! $window.FormData) { - throw new Error('Unsupported browser version'); - } + ApiMiddleware.prototype.upload = function(files, path) { + if (! $window.FormData) { + throw new Error('Unsupported browser version'); + } - var destination = this.getPath(path); + var destination = this.getPath(path); - return this.apiHandler.upload(fileManagerConfig.uploadUrl, destination, files); - }; + return this.apiHandler.upload(fileManagerConfig.uploadUrl, destination, files); + }; - ApiMiddleware.prototype.getContent = function(item) { - var itemPath = this.getFilePath(item); - return this.apiHandler.getContent(fileManagerConfig.getContentUrl, itemPath); - }; + ApiMiddleware.prototype.getContent = function(item) { + var itemPath = this.getFilePath(item); + return this.apiHandler.getContent(fileManagerConfig.getContentUrl, itemPath); + }; - ApiMiddleware.prototype.edit = function(item) { - var itemPath = this.getFilePath(item); - return this.apiHandler.edit(fileManagerConfig.editUrl, itemPath, item.tempModel.content); - }; + ApiMiddleware.prototype.edit = function(item) { + var itemPath = this.getFilePath(item); + return this.apiHandler.edit(fileManagerConfig.editUrl, itemPath, item.tempModel.content); + }; - ApiMiddleware.prototype.rename = function(item) { - var itemPath = this.getFilePath(item); - var newPath = item.tempModel.fullPath(); - return this.apiHandler.rename(fileManagerConfig.renameUrl, itemPath, newPath); - }; + ApiMiddleware.prototype.rename = function(item) { + var itemPath = this.getFilePath(item); + var newPath = item.tempModel.fullPath(); + return this.apiHandler.rename(fileManagerConfig.renameUrl, itemPath, newPath); + }; - ApiMiddleware.prototype.getUrl = function(item) { - var itemPath = this.getFilePath(item); - return this.apiHandler.getUrl(fileManagerConfig.downloadFileUrl, itemPath); - }; + ApiMiddleware.prototype.getUrl = function(item) { + var itemPath = this.getFilePath(item); + return this.apiHandler.getUrl(fileManagerConfig.downloadFileUrl, itemPath); + }; - ApiMiddleware.prototype.getThumbnailUrl = function(item) { - var itemPath = this.getFilePath(item); - return fileManagerConfig.thumbnailUrlPrefix + this.apiHandler.getUrl(fileManagerConfig.downloadFileUrl, itemPath) + fileManagerConfig.thumbnailUrlSuffix; - }; + ApiMiddleware.prototype.getThumbnailUrl = function(item) { + var itemPath = this.getFilePath(item); + return fileManagerConfig.thumbnailUrlPrefix + this.apiHandler.getUrl(fileManagerConfig.downloadFileUrl, itemPath) + fileManagerConfig.thumbnailUrlSuffix; + }; - ApiMiddleware.prototype.download = function(item, forceNewWindow) { - var itemPath = this.getFilePath(item); - var toFilename = item.model.name; + ApiMiddleware.prototype.enableThumbnails = function () { + return fileManagerConfig.enableThumbnails; + }; + + ApiMiddleware.prototype.enableIconPreviewView = function () { + return fileManagerConfig.enableIconPreviewView; + }; - if (item.isFolder()) { - return; - } + ApiMiddleware.prototype.download = function(item, forceNewWindow) { + var itemPath = this.getFilePath(item); + var toFilename = item.model.name; - return this.apiHandler.download( - fileManagerConfig.downloadFileUrl, - itemPath, - toFilename, - fileManagerConfig.downloadFilesByAjax, - forceNewWindow - ); - }; + if (item.isFolder()) { + return; + } + + return this.apiHandler.download( + fileManagerConfig.downloadFileUrl, + itemPath, + toFilename, + fileManagerConfig.downloadFilesByAjax, + forceNewWindow + ); + }; - ApiMiddleware.prototype.downloadMultiple = function(files, forceNewWindow) { - var items = this.getFileList(files); - var timestamp = new Date().getTime().toString().substr(8, 13); - var toFilename = timestamp + '-' + fileManagerConfig.multipleDownloadFileName; - - return this.apiHandler.downloadMultiple( - fileManagerConfig.downloadMultipleUrl, - items, - toFilename, - fileManagerConfig.downloadFilesByAjax, - forceNewWindow - ); - }; + ApiMiddleware.prototype.downloadMultiple = function(files, forceNewWindow) { + var items = this.getFileList(files); + var timestamp = new Date().getTime().toString().substr(8, 13); + var toFilename = timestamp + '-' + fileManagerConfig.multipleDownloadFileName; + + return this.apiHandler.downloadMultiple( + fileManagerConfig.downloadMultipleUrl, + items, + toFilename, + fileManagerConfig.downloadFilesByAjax, + forceNewWindow + ); + }; - ApiMiddleware.prototype.compress = function(files, compressedFilename, path) { - var items = this.getFileList(files); - return this.apiHandler.compress(fileManagerConfig.compressUrl, items, compressedFilename, this.getPath(path)); - }; + ApiMiddleware.prototype.compress = function(files, compressedFilename, path) { + var items = this.getFileList(files); + return this.apiHandler.compress(fileManagerConfig.compressUrl, items, compressedFilename, this.getPath(path)); + }; - ApiMiddleware.prototype.extract = function(item, folderName, path) { - var itemPath = this.getFilePath(item); - return this.apiHandler.extract(fileManagerConfig.extractUrl, itemPath, folderName, this.getPath(path)); - }; + ApiMiddleware.prototype.extract = function(item, folderName, path) { + var itemPath = this.getFilePath(item); + return this.apiHandler.extract(fileManagerConfig.extractUrl, itemPath, folderName, this.getPath(path)); + }; - ApiMiddleware.prototype.changePermissions = function(item) { - return this.apiHandler.changePermissions(fileManagerConfig.permissionsUrl, item); - }; + ApiMiddleware.prototype.changePermissions = function(item) { + return this.apiHandler.changePermissions(fileManagerConfig.permissionsUrl, item); + }; - ApiMiddleware.prototype.createFolder = function(item) { - item.tempModel.name = this.apiHandler.slug(item.tempModel.name); - var path = item.tempModel.fullPath(); - return this.apiHandler.createFolder(fileManagerConfig.createFolderUrl, path); - }; + ApiMiddleware.prototype.createFolder = function(item) { + item.tempModel.name = this.apiHandler.slug(item.tempModel.name); + var path = item.tempModel.fullPath(); + return this.apiHandler.createFolder(fileManagerConfig.createFolderUrl, path); + }; - return ApiMiddleware; + return ApiMiddleware; - }]); + }]); })(angular); (function(angular) { 'use strict'; angular.module('FileManagerApp').service('fileNavigator', [ 'apiMiddleware', 'fileManagerConfig', 'item', function (ApiMiddleware, fileManagerConfig, Item) { - var FileNavigator = function() { - this.apiMiddleware = new ApiMiddleware(); - this.requesting = false; - this.fileList = []; - this.currentPath = []; - this.history = []; - this.error = ''; + var FileNavigator = function() { + this.apiMiddleware = new ApiMiddleware(); + this.requesting = false; + this.fileList = []; + this.currentPath = []; + this.history = []; + this.error = ''; - this.onRefresh = function() {}; - }; + this.onRefresh = function() {}; + }; - FileNavigator.prototype.deferredHandler = function(data, deferred, code, defaultMsg) { - if (!data || typeof data !== 'object') { - this.error = 'Error %s - Bridge response error, please check the API docs or this ajax response.'.replace('%s', code); - } - if (code == 404) { - this.error = 'Error 404 - Backend bridge is not working, please check the ajax response.'; - } - if (!this.error && data.result && data.result.error) { - this.error = data.result.error; - } - if (!this.error && data.error) { - this.error = data.error.message; - } - if (!this.error && defaultMsg) { - this.error = defaultMsg; - } - if (this.error) { - return deferred.reject(data); - } - return deferred.resolve(data); - }; + FileNavigator.prototype.deferredHandler = function(data, deferred, code, defaultMsg) { + if (!data || typeof data !== 'object') { + this.error = 'Error %s - Bridge response error, please check the API docs or this ajax response.'.replace('%s', code); + } + if (code == 404) { + this.error = 'Error 404 - Backend bridge is not working, please check the ajax response.'; + } + if (!this.error && data.result && data.result.error) { + this.error = data.result.error; + } + if (!this.error && data.error) { + this.error = data.error.message; + } + if (!this.error && defaultMsg) { + this.error = defaultMsg; + } + if (this.error) { + return deferred.reject(data); + } + return deferred.resolve(data); + }; - FileNavigator.prototype.list = function(recycle) { - return this.apiMiddleware.list(this.currentPath, this.deferredHandler.bind(this), recycle); - }; + FileNavigator.prototype.list = function(recycle) { + return this.apiMiddleware.list(this.currentPath, this.deferredHandler.bind(this), recycle); + }; - FileNavigator.prototype.refresh = function(recycle) { - var self = this; - var path = self.currentPath.join('/'); - self.requesting = true; - self.fileList = []; - return self.list(recycle).then(function(data) { - self.fileList = (data.result || []).map(function(file) { - return new Item(file, self.currentPath); - }); - self.buildTree(path); - self.onRefresh(); - }).finally(function() { - self.requesting = false; + FileNavigator.prototype.refresh = function(recycle) { + var self = this; + var path = self.currentPath.join('/'); + self.requesting = true; + self.fileList = []; + return self.list(recycle).then(function(data) { + self.fileList = (data.result || []).map(function (file) { + return new Item(file, self.currentPath); }); - }; - - FileNavigator.prototype.buildTree = function(path) { - var flatNodes = [], selectedNode = {}; - - function recursive(parent, item, path) { - var absName = path ? (path + '/' + item.model.name) : item.model.name; - if (parent.name.trim() && path.trim().indexOf(parent.name) !== 0) { - parent.nodes = []; - } - if (parent.name !== path) { - parent.nodes.forEach(function(nd) { - recursive(nd, item, path); - }); - } else { - for (var e in parent.nodes) { - if (parent.nodes[e].name === absName) { - return; - } - } - parent.nodes.push({item: item, name: absName, nodes: []}); - } - - parent.nodes = parent.nodes.sort(function(a, b) { - return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : a.name.toLowerCase() === b.name.toLowerCase() ? 0 : 1; + self.buildTree(path); + self.onRefresh(); + }).finally(function() { + self.requesting = false; + }); + }; + + FileNavigator.prototype.buildTree = function(path) { + var flatNodes = [], selectedNode = {}; + + function recursive(parent, item, path) { + var absName = path ? (path + '/' + item.model.name) : item.model.name; + if (parent.name.trim() && path.trim().indexOf(parent.name) !== 0) { + parent.nodes = []; + } + if (parent.name !== path) { + parent.nodes.forEach(function(nd) { + recursive(nd, item, path); }); - } - - function flatten(node, array) { - array.push(node); - for (var n in node.nodes) { - flatten(node.nodes[n], array); + } else { + for (var e in parent.nodes) { + if (parent.nodes[e].name === absName) { + return; + } } + parent.nodes.push({item: item, name: absName, nodes: []}); } + + parent.nodes = parent.nodes.sort(function(a, b) { + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : a.name.toLowerCase() === b.name.toLowerCase() ? 0 : 1; + }); + } - function findNode(data, path) { - return data.filter(function (n) { - return n.name === path; - })[0]; + function flatten(node, array) { + array.push(node); + for (var n in node.nodes) { + flatten(node.nodes[n], array); } + } - !this.history.length && this.history.push({name: '', nodes: []}); - flatten(this.history[0], flatNodes); - selectedNode = findNode(flatNodes, path); - selectedNode && (selectedNode.nodes = []); + function findNode(data, path) { + return data.filter(function (n) { + return n.name === path; + })[0]; + } - for (var o in this.fileList) { - var item = this.fileList[o]; - item instanceof Item && item.isFolder() && recursive(this.history[0], item, path); - } - }; + !this.history.length && this.history.push({name: '', nodes: []}); + flatten(this.history[0], flatNodes); + selectedNode = findNode(flatNodes, path); + selectedNode && (selectedNode.nodes = []); - FileNavigator.prototype.folderClick = function(item) { - this.currentPath = []; - if (item && item.isFolder()) { - this.currentPath = item.model.fullPath().split('/').splice(1); - } - this.refresh(); - }; + for (var o in this.fileList) { + var item = this.fileList[o]; + item instanceof Item && item.isFolder() && recursive(this.history[0], item, path); + } + }; - FileNavigator.prototype.upDir = function() { - if (this.currentPath[0]) { - this.currentPath = this.currentPath.slice(0, -1); - this.refresh(); - } - }; + FileNavigator.prototype.folderClick = function(item) { + this.currentPath = []; + if (item && item.isFolder()) { + this.currentPath = item.model.fullPath().split('/').splice(1); + } + this.refresh(); + }; - FileNavigator.prototype.goTo = function(index) { - this.currentPath = this.currentPath.slice(0, index + 1); + FileNavigator.prototype.upDir = function() { + if (this.currentPath[0]) { + this.currentPath = this.currentPath.slice(0, -1); this.refresh(); - }; + } + }; - FileNavigator.prototype.fileNameExists = function(fileName) { - return this.fileList.find(function(item) { - return fileName.trim && item.model.name.trim() === fileName.trim(); - }); - }; + FileNavigator.prototype.goTo = function(index) { + this.currentPath = this.currentPath.slice(0, index + 1); + this.refresh(); + }; - FileNavigator.prototype.listHasFolders = function() { - return this.fileList.find(function(item) { - return item.model.type === 'dir'; - }); - }; + FileNavigator.prototype.fileNameExists = function(fileName) { + return this.fileList.find(function(item) { + return fileName.trim && item.model.name.trim() === fileName.trim(); + }); + }; + + FileNavigator.prototype.listHasFolders = function() { + return this.fileList.find(function(item) { + return item.model.type === 'dir'; + }); + }; - return FileNavigator; - }]); + return FileNavigator; + }]); })(angular); -/* +/* * Angular JS Multi Select - * Creates a dropdown-like button with checkboxes. + * Creates a dropdown-like button with checkboxes. * * Project started on: Tue, 14 Jan 2014 - 5:18:02 PM * Current version: 4.0.0 - * + * * Released under the MIT License * -------------------------------------------------------------------------------- * The MIT License (MIT) * * Copyright (c) 2014 Ignatius Steven (https://github.com/isteven) * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all + * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * -------------------------------------------------------------------------------- */ @@ -2725,52 +2738,52 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' , [ '$sce', '$timeout', '$templateCache', function ( $sce, $timeout, $templateCache ) { return { - restrict: + restrict: 'AE', - scope: - { - // models - inputModel : '=', - outputModel : '=', - - // settings based on attribute - isDisabled : '=', - - // callbacks - onClear : '&', - onClose : '&', - onSearchChange : '&', - onItemClick : '&', - onOpen : '&', - onReset : '&', - onSelectAll : '&', - onSelectNone : '&', - - // i18n - translation : '=' - }, - - /* + scope: + { + // models + inputModel : '=', + outputModel : '=', + + // settings based on attribute + isDisabled : '=', + + // callbacks + onClear : '&', + onClose : '&', + onSearchChange : '&', + onItemClick : '&', + onOpen : '&', + onReset : '&', + onSelectAll : '&', + onSelectNone : '&', + + // i18n + translation : '=' + }, + + /* * The rest are attributes. They don't need to be parsed / binded, so we can safely access them by value. * - buttonLabel, directiveId, helperElements, itemLabel, maxLabels, orientation, selectionMode, minSearchLength, * tickProperty, disableProperty, groupProperty, searchProperty, maxHeight, outputProperties */ + + templateUrl: + 'isteven-multi-select.htm', - templateUrl: - 'isteven-multi-select.htm', - - link: function ( $scope, element, attrs ) { + link: function ( $scope, element, attrs ) { $scope.backUp = []; - $scope.varButtonLabel = ''; + $scope.varButtonLabel = ''; $scope.spacingProperty = ''; - $scope.indexProperty = ''; + $scope.indexProperty = ''; $scope.orientationH = false; $scope.orientationV = true; $scope.filteredModel = []; - $scope.inputLabel = { labelFilter: '' }; - $scope.tabIndex = 0; + $scope.inputLabel = { labelFilter: '' }; + $scope.tabIndex = 0; $scope.lang = {}; $scope.helperStatus = { all : true, @@ -2779,7 +2792,7 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' filter : true }; - var + var prevTabIndex = 0, helperItems = [], helperItemsLength = 0, @@ -2788,38 +2801,38 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' selectedItems = [], formElements = [], vMinSearchLength = 0, - clickedItem = null + clickedItem = null // v3.0.0 // clear button clicked - $scope.clearClicked = function( e ) { + $scope.clearClicked = function( e ) { $scope.inputLabel.labelFilter = ''; $scope.updateFilter(); - $scope.select( 'clear', e ); + $scope.select( 'clear', e ); } // A little hack so that AngularJS ng-repeat can loop using start and end index like a normal loop // http://stackoverflow.com/questions/16824853/way-to-ng-repeat-defined-number-of-times-instead-of-repeating-over-array $scope.numberToArray = function( num ) { - return new Array( num ); + return new Array( num ); } // Call this function when user type on the filter field - $scope.searchChanged = function() { + $scope.searchChanged = function() { if ( $scope.inputLabel.labelFilter.length < vMinSearchLength && $scope.inputLabel.labelFilter.length > 0 ) { return false; - } + } $scope.updateFilter(); } $scope.updateFilter = function() - { + { // we check by looping from end of input-model $scope.filteredModel = []; var i = 0; if ( typeof $scope.inputModel === 'undefined' ) { - return false; + return false; } for( i = $scope.inputModel.length - 1; i >= 0; i-- ) { @@ -2828,39 +2841,39 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' if ( typeof $scope.inputModel[ i ][ attrs.groupProperty ] !== 'undefined' && $scope.inputModel[ i ][ attrs.groupProperty ] === false ) { $scope.filteredModel.push( $scope.inputModel[ i ] ); } - - // if it's data + + // if it's data var gotData = false; - if ( typeof $scope.inputModel[ i ][ attrs.groupProperty ] === 'undefined' ) { - - // If we set the search-key attribute, we use this loop. + if ( typeof $scope.inputModel[ i ][ attrs.groupProperty ] === 'undefined' ) { + + // If we set the search-key attribute, we use this loop. if ( typeof attrs.searchProperty !== 'undefined' && attrs.searchProperty !== '' ) { for (var key in $scope.inputModel[ i ] ) { - if ( + if ( typeof $scope.inputModel[ i ][ key ] !== 'boolean' - && String( $scope.inputModel[ i ][ key ] ).toUpperCase().indexOf( $scope.inputLabel.labelFilter.toUpperCase() ) >= 0 + && String( $scope.inputModel[ i ][ key ] ).toUpperCase().indexOf( $scope.inputLabel.labelFilter.toUpperCase() ) >= 0 && attrs.searchProperty.indexOf( key ) > -1 ) { gotData = true; break; } - } + } } // if there's no search-key attribute, we use this one. Much better on performance. else { for ( var key in $scope.inputModel[ i ] ) { - if ( + if ( typeof $scope.inputModel[ i ][ key ] !== 'boolean' - && String( $scope.inputModel[ i ][ key ] ).toUpperCase().indexOf( $scope.inputLabel.labelFilter.toUpperCase() ) >= 0 + && String( $scope.inputModel[ i ][ key ] ).toUpperCase().indexOf( $scope.inputLabel.labelFilter.toUpperCase() ) >= 0 ) { gotData = true; break; } - } + } } - if ( gotData === true ) { + if ( gotData === true ) { // push $scope.filteredModel.push( $scope.inputModel[ i ] ); } @@ -2869,79 +2882,79 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' // if it's group start if ( typeof $scope.inputModel[ i ][ attrs.groupProperty ] !== 'undefined' && $scope.inputModel[ i ][ attrs.groupProperty ] === true ) { - if ( typeof $scope.filteredModel[ $scope.filteredModel.length - 1 ][ attrs.groupProperty ] !== 'undefined' - && $scope.filteredModel[ $scope.filteredModel.length - 1 ][ attrs.groupProperty ] === false ) { + if ( typeof $scope.filteredModel[ $scope.filteredModel.length - 1 ][ attrs.groupProperty ] !== 'undefined' + && $scope.filteredModel[ $scope.filteredModel.length - 1 ][ attrs.groupProperty ] === false ) { $scope.filteredModel.pop(); } else { $scope.filteredModel.push( $scope.inputModel[ i ] ); } } - } - - $scope.filteredModel.reverse(); - - $timeout( function() { + } - $scope.getFormElements(); + $scope.filteredModel.reverse(); + + $timeout( function() { - // Callback: on filter change + $scope.getFormElements(); + + // Callback: on filter change if ( $scope.inputLabel.labelFilter.length > vMinSearchLength ) { var filterObj = []; angular.forEach( $scope.filteredModel, function( value, key ) { - if ( typeof value !== 'undefined' ) { - if ( typeof value[ attrs.groupProperty ] === 'undefined' ) { + if ( typeof value !== 'undefined' ) { + if ( typeof value[ attrs.groupProperty ] === 'undefined' ) { var tempObj = angular.copy( value ); - var index = filterObj.push( tempObj ); + var index = filterObj.push( tempObj ); delete filterObj[ index - 1 ][ $scope.indexProperty ]; - delete filterObj[ index - 1 ][ $scope.spacingProperty ]; + delete filterObj[ index - 1 ][ $scope.spacingProperty ]; } } }); - $scope.onSearchChange({ - data: - { - keyword: $scope.inputLabel.labelFilter, - result: filterObj - } + $scope.onSearchChange({ + data: + { + keyword: $scope.inputLabel.labelFilter, + result: filterObj + } }); } },0); }; // List all the input elements. We need this for our keyboard navigation. - // This function will be called everytime the filter is updated. + // This function will be called everytime the filter is updated. // Depending on the size of filtered mode, might not good for performance, but oh well.. - $scope.getFormElements = function() { + $scope.getFormElements = function() { formElements = []; - var + var selectButtons = [], inputField = [], checkboxes = [], clearButton = []; - + // If available, then get select all, select none, and reset buttons - if ( $scope.helperStatus.all || $scope.helperStatus.none || $scope.helperStatus.reset ) { - selectButtons = element.children().children().next().children().children()[ 0 ].getElementsByTagName( 'button' ); + if ( $scope.helperStatus.all || $scope.helperStatus.none || $scope.helperStatus.reset ) { + selectButtons = element.children().children().next().children().children()[ 0 ].getElementsByTagName( 'button' ); // If available, then get the search box and the clear button - if ( $scope.helperStatus.filter ) { - // Get helper - search and clear button. - inputField = element.children().children().next().children().children().next()[ 0 ].getElementsByTagName( 'input' ); - clearButton = element.children().children().next().children().children().next()[ 0 ].getElementsByTagName( 'button' ); + if ( $scope.helperStatus.filter ) { + // Get helper - search and clear button. + inputField = element.children().children().next().children().children().next()[ 0 ].getElementsByTagName( 'input' ); + clearButton = element.children().children().next().children().children().next()[ 0 ].getElementsByTagName( 'button' ); } } else { - if ( $scope.helperStatus.filter ) { - // Get helper - search and clear button. - inputField = element.children().children().next().children().children()[ 0 ].getElementsByTagName( 'input' ); + if ( $scope.helperStatus.filter ) { + // Get helper - search and clear button. + inputField = element.children().children().next().children().children()[ 0 ].getElementsByTagName( 'input' ); clearButton = element.children().children().next().children().children()[ 0 ].getElementsByTagName( 'button' ); } } - + // Get checkboxes if ( !$scope.helperStatus.all && !$scope.helperStatus.none && !$scope.helperStatus.reset && !$scope.helperStatus.filter ) { checkboxes = element.children().children().next()[ 0 ].getElementsByTagName( 'input' ); @@ -2950,58 +2963,58 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' checkboxes = element.children().children().next().children().next()[ 0 ].getElementsByTagName( 'input' ); } - // Push them into global array formElements[] + // Push them into global array formElements[] for ( var i = 0; i < selectButtons.length ; i++ ) { formElements.push( selectButtons[ i ] ); } for ( var i = 0; i < inputField.length ; i++ ) { formElements.push( inputField[ i ] ); } for ( var i = 0; i < clearButton.length ; i++ ) { formElements.push( clearButton[ i ] ); } - for ( var i = 0; i < checkboxes.length ; i++ ) { formElements.push( checkboxes[ i ] ); } - } + for ( var i = 0; i < checkboxes.length ; i++ ) { formElements.push( checkboxes[ i ] ); } + } // check if an item has attrs.groupProperty (be it true or false) $scope.isGroupMarker = function( item , type ) { - if ( typeof item[ attrs.groupProperty ] !== 'undefined' && item[ attrs.groupProperty ] === type ) return true; + if ( typeof item[ attrs.groupProperty ] !== 'undefined' && item[ attrs.groupProperty ] === type ) return true; return false; } $scope.removeGroupEndMarker = function( item ) { - if ( typeof item[ attrs.groupProperty ] !== 'undefined' && item[ attrs.groupProperty ] === false ) return false; + if ( typeof item[ attrs.groupProperty ] !== 'undefined' && item[ attrs.groupProperty ] === false ) return false; return true; - } + } // call this function when an item is clicked - $scope.syncItems = function( item, e, ng_repeat_index ) { + $scope.syncItems = function( item, e, ng_repeat_index ) { e.preventDefault(); e.stopPropagation(); // if the directive is globaly disabled, do nothing - if ( typeof attrs.disableProperty !== 'undefined' && item[ attrs.disableProperty ] === true ) { + if ( typeof attrs.disableProperty !== 'undefined' && item[ attrs.disableProperty ] === true ) { return false; } // if item is disabled, do nothing - if ( typeof attrs.isDisabled !== 'undefined' && $scope.isDisabled === true ) { + if ( typeof attrs.isDisabled !== 'undefined' && $scope.isDisabled === true ) { return false; - } + } // if end group marker is clicked, do nothing if ( typeof item[ attrs.groupProperty ] !== 'undefined' && item[ attrs.groupProperty ] === false ) { return false; - } + } - var index = $scope.filteredModel.indexOf( item ); + var index = $scope.filteredModel.indexOf( item ); // if the start of group marker is clicked ( only for multiple selection! ) // how it works: // - if, in a group, there are items which are not selected, then they all will be selected - // - if, in a group, all items are selected, then they all will be de-selected - if ( typeof item[ attrs.groupProperty ] !== 'undefined' && item[ attrs.groupProperty ] === true ) { + // - if, in a group, all items are selected, then they all will be de-selected + if ( typeof item[ attrs.groupProperty ] !== 'undefined' && item[ attrs.groupProperty ] === true ) { // this is only for multiple selection, so if selection mode is single, do nothing if ( typeof attrs.selectionMode !== 'undefined' && attrs.selectionMode.toUpperCase() === 'SINGLE' ) { return false; } - + var i,j,k; var startIndex = 0; var endIndex = $scope.filteredModel.length - 1; @@ -3010,44 +3023,44 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' // nest level is to mark the depth of the group. // when you get into a group (start group marker), nestLevel++ // when you exit a group (end group marker), nextLevel-- - var nestLevel = 0; + var nestLevel = 0; // we loop throughout the filtered model (not whole model) - for( i = index ; i < $scope.filteredModel.length ; i++) { + for( i = index ; i < $scope.filteredModel.length ; i++) { // this break will be executed when we're done processing each group - if ( nestLevel === 0 && i > index ) + if ( nestLevel === 0 && i > index ) { break; } - + if ( typeof $scope.filteredModel[ i ][ attrs.groupProperty ] !== 'undefined' && $scope.filteredModel[ i ][ attrs.groupProperty ] === true ) { - + // To cater multi level grouping if ( tempArr.length === 0 ) { - startIndex = i + 1; - } + startIndex = i + 1; + } nestLevel = nestLevel + 1; - } + } // if group end else if ( typeof $scope.filteredModel[ i ][ attrs.groupProperty ] !== 'undefined' && $scope.filteredModel[ i ][ attrs.groupProperty ] === false ) { - nestLevel = nestLevel - 1; + nestLevel = nestLevel - 1; - // cek if all are ticked or not - if ( tempArr.length > 0 && nestLevel === 0 ) { + // cek if all are ticked or not + if ( tempArr.length > 0 && nestLevel === 0 ) { - var allTicked = true; + var allTicked = true; endIndex = i; - for ( j = 0; j < tempArr.length ; j++ ) { + for ( j = 0; j < tempArr.length ; j++ ) { if ( typeof tempArr[ j ][ $scope.tickProperty ] !== 'undefined' && tempArr[ j ][ $scope.tickProperty ] === false ) { allTicked = false; break; } - } + } if ( allTicked === true ) { for ( j = startIndex; j <= endIndex ; j++ ) { @@ -3065,19 +3078,19 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' $scope.inputModel[ inputModelIndex ][ $scope.tickProperty ] = false; } } - } + } } else { for ( j = startIndex; j <= endIndex ; j++ ) { if ( typeof $scope.filteredModel[ j ][ attrs.groupProperty ] === 'undefined' ) { if ( typeof attrs.disableProperty === 'undefined' ) { - $scope.filteredModel[ j ][ $scope.tickProperty ] = true; + $scope.filteredModel[ j ][ $scope.tickProperty ] = true; // we refresh input model as well inputModelIndex = $scope.filteredModel[ j ][ $scope.indexProperty ]; $scope.inputModel[ inputModelIndex ][ $scope.tickProperty ] = true; - } + } else if ( $scope.filteredModel[ j ][ attrs.disableProperty ] !== true ) { $scope.filteredModel[ j ][ $scope.tickProperty ] = true; // we refresh input model as well @@ -3085,16 +3098,16 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' $scope.inputModel[ inputModelIndex ][ $scope.tickProperty ] = true; } } - } - } + } + } } } - + // if data - else { - tempArr.push( $scope.filteredModel[ i ] ); + else { + tempArr.push( $scope.filteredModel[ i ] ); } - } + } } // if an item (not group marker) is clicked @@ -3102,18 +3115,18 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' // If it's single selection mode if ( typeof attrs.selectionMode !== 'undefined' && attrs.selectionMode.toUpperCase() === 'SINGLE' ) { - + // first, set everything to false - for( i=0 ; i < $scope.filteredModel.length ; i++) { - $scope.filteredModel[ i ][ $scope.tickProperty ] = false; - } - for( i=0 ; i < $scope.inputModel.length ; i++) { - $scope.inputModel[ i ][ $scope.tickProperty ] = false; - } - + for( i=0 ; i < $scope.filteredModel.length ; i++) { + $scope.filteredModel[ i ][ $scope.tickProperty ] = false; + } + for( i=0 ; i < $scope.inputModel.length ; i++) { + $scope.inputModel[ i ][ $scope.tickProperty ] = false; + } + // then set the clicked item to true - $scope.filteredModel[ index ][ $scope.tickProperty ] = true; - } + $scope.filteredModel[ index ][ $scope.tickProperty ] = true; + } // Multiple else { @@ -3121,29 +3134,29 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' } // we refresh input model as well - var inputModelIndex = $scope.filteredModel[ index ][ $scope.indexProperty ]; - $scope.inputModel[ inputModelIndex ][ $scope.tickProperty ] = $scope.filteredModel[ index ][ $scope.tickProperty ]; - } + var inputModelIndex = $scope.filteredModel[ index ][ $scope.indexProperty ]; + $scope.inputModel[ inputModelIndex ][ $scope.tickProperty ] = $scope.filteredModel[ index ][ $scope.tickProperty ]; + } // we execute the callback function here - clickedItem = angular.copy( item ); - if ( clickedItem !== null ) { + clickedItem = angular.copy( item ); + if ( clickedItem !== null ) { $timeout( function() { delete clickedItem[ $scope.indexProperty ]; - delete clickedItem[ $scope.spacingProperty ]; + delete clickedItem[ $scope.spacingProperty ]; $scope.onItemClick( { data: clickedItem } ); - clickedItem = null; - }, 0 ); - } - + clickedItem = null; + }, 0 ); + } + $scope.refreshOutputModel(); - $scope.refreshButton(); + $scope.refreshButton(); // We update the index here prevTabIndex = $scope.tabIndex; $scope.tabIndex = ng_repeat_index + helperItemsLength; - - // Set focus on the hidden checkbox + + // Set focus on the hidden checkbox e.target.focus(); // set & remove CSS style @@ -3152,67 +3165,67 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' if ( typeof attrs.selectionMode !== 'undefined' && attrs.selectionMode.toUpperCase() === 'SINGLE' ) { // on single selection mode, we then hide the checkbox layer - $scope.toggleCheckboxes( e ); + $scope.toggleCheckboxes( e ); } - } + } // update $scope.outputModel - $scope.refreshOutputModel = function() { - + $scope.refreshOutputModel = function() { + $scope.outputModel = []; - var + var outputProps = [], tempObj = {}; // v4.0.0 - if ( typeof attrs.outputProperties !== 'undefined' ) { - outputProps = attrs.outputProperties.split(' '); - angular.forEach( $scope.inputModel, function( value, key ) { - if ( - typeof value !== 'undefined' - && typeof value[ attrs.groupProperty ] === 'undefined' - && value[ $scope.tickProperty ] === true + if ( typeof attrs.outputProperties !== 'undefined' ) { + outputProps = attrs.outputProperties.split(' '); + angular.forEach( $scope.inputModel, function( value, key ) { + if ( + typeof value !== 'undefined' + && typeof value[ attrs.groupProperty ] === 'undefined' + && value[ $scope.tickProperty ] === true ) { tempObj = {}; - angular.forEach( value, function( value1, key1 ) { - if ( outputProps.indexOf( key1 ) > -1 ) { - tempObj[ key1 ] = value1; + angular.forEach( value, function( value1, key1 ) { + if ( outputProps.indexOf( key1 ) > -1 ) { + tempObj[ key1 ] = value1; } }); - var index = $scope.outputModel.push( tempObj ); + var index = $scope.outputModel.push( tempObj ); delete $scope.outputModel[ index - 1 ][ $scope.indexProperty ]; - delete $scope.outputModel[ index - 1 ][ $scope.spacingProperty ]; + delete $scope.outputModel[ index - 1 ][ $scope.spacingProperty ]; } - }); + }); } else { - angular.forEach( $scope.inputModel, function( value, key ) { - if ( - typeof value !== 'undefined' - && typeof value[ attrs.groupProperty ] === 'undefined' - && value[ $scope.tickProperty ] === true + angular.forEach( $scope.inputModel, function( value, key ) { + if ( + typeof value !== 'undefined' + && typeof value[ attrs.groupProperty ] === 'undefined' + && value[ $scope.tickProperty ] === true ) { var temp = angular.copy( value ); - var index = $scope.outputModel.push( temp ); + var index = $scope.outputModel.push( temp ); delete $scope.outputModel[ index - 1 ][ $scope.indexProperty ]; - delete $scope.outputModel[ index - 1 ][ $scope.spacingProperty ]; + delete $scope.outputModel[ index - 1 ][ $scope.spacingProperty ]; } - }); + }); } } // refresh button label $scope.refreshButton = function() { - $scope.varButtonLabel = ''; - var ctr = 0; + $scope.varButtonLabel = ''; + var ctr = 0; // refresh button label... if ( $scope.outputModel.length === 0 ) { - // https://github.com/isteven/angular-multi-select/pull/19 + // https://github.com/isteven/angular-multi-select/pull/19 $scope.varButtonLabel = $scope.lang.nothingSelected; } - else { + else { var tempMaxLabels = $scope.outputModel.length; if ( typeof attrs.maxLabels !== 'undefined' && attrs.maxLabels !== '' ) { tempMaxLabels = attrs.maxLabels; @@ -3224,85 +3237,85 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' } else { $scope.more = false; - } - + } + angular.forEach( $scope.inputModel, function( value, key ) { - if ( typeof value !== 'undefined' && value[ attrs.tickProperty ] === true ) { - if ( ctr < tempMaxLabels ) { + if ( typeof value !== 'undefined' && value[ attrs.tickProperty ] === true ) { + if ( ctr < tempMaxLabels ) { $scope.varButtonLabel += ( $scope.varButtonLabel.length > 0 ? ',
' : '
') + $scope.writeLabel( value, 'buttonLabel' ); } ctr++; } - }); + }); if ( $scope.more === true ) { // https://github.com/isteven/angular-multi-select/pull/16 if (tempMaxLabels > 0) { $scope.varButtonLabel += ', ... '; } - $scope.varButtonLabel += '(' + $scope.outputModel.length + ')'; + $scope.varButtonLabel += '(' + $scope.outputModel.length + ')'; } } - $scope.varButtonLabel = $sce.trustAsHtml( $scope.varButtonLabel + '' ); + $scope.varButtonLabel = $sce.trustAsHtml( $scope.varButtonLabel + '' ); } // Check if a checkbox is disabled or enabled. It will check the granular control (disableProperty) and global control (isDisabled) // Take note that the granular control has higher priority. $scope.itemIsDisabled = function( item ) { - - if ( typeof attrs.disableProperty !== 'undefined' && item[ attrs.disableProperty ] === true ) { + + if ( typeof attrs.disableProperty !== 'undefined' && item[ attrs.disableProperty ] === true ) { return true; } - else { - if ( $scope.isDisabled === true ) { + else { + if ( $scope.isDisabled === true ) { return true; } else { return false; } } - + } // A simple function to parse the item label settings. Used on the buttons and checkbox labels. $scope.writeLabel = function( item, type ) { - + // type is either 'itemLabel' or 'buttonLabel' - var temp = attrs[ type ].split( ' ' ); - var label = ''; + var temp = attrs[ type ].split( ' ' ); + var label = ''; - angular.forEach( temp, function( value, key ) { + angular.forEach( temp, function( value, key ) { item[ value ] && ( label += ' ' + value.split( '.' ).reduce( function( prev, current ) { - return prev[ current ]; - }, item )); + return prev[ current ]; + }, item )); }); - - if ( type.toUpperCase() === 'BUTTONLABEL' ) { + + if ( type.toUpperCase() === 'BUTTONLABEL' ) { return label; } return $sce.trustAsHtml( label ); - } + } // UI operations to show/hide checkboxes based on click event.. - $scope.toggleCheckboxes = function( e ) { - + $scope.toggleCheckboxes = function( e ) { + // We grab the button var clickedEl = element.children()[0]; // Just to make sure.. had a bug where key events were recorded twice angular.element( document ).off( 'click', $scope.externalClickListener ); - angular.element( document ).off( 'keydown', $scope.keyboardListener ); + angular.element( document ).off( 'keydown', $scope.keyboardListener ); - // The idea below was taken from another multi-select directive - https://github.com/amitava82/angular-multiselect - // His version is awesome if you need a more simple multi-select approach. + // The idea below was taken from another multi-select directive - https://github.com/amitava82/angular-multiselect + // His version is awesome if you need a more simple multi-select approach. // close - if ( angular.element( checkBoxLayer ).hasClass( 'show' )) { + if ( angular.element( checkBoxLayer ).hasClass( 'show' )) { - angular.element( checkBoxLayer ).removeClass( 'show' ); - angular.element( clickedEl ).removeClass( 'buttonClicked' ); + angular.element( checkBoxLayer ).removeClass( 'show' ); + angular.element( clickedEl ).removeClass( 'buttonClicked' ); angular.element( document ).off( 'click', $scope.externalClickListener ); - angular.element( document ).off( 'keydown', $scope.keyboardListener ); + angular.element( document ).off( 'keydown', $scope.keyboardListener ); // clear the focused element; $scope.removeFocusStyle( $scope.tabIndex ); @@ -3317,80 +3330,80 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' // set focus on button again element.children().children()[ 0 ].focus(); - } + } // open - else - { + else + { // clear filter - $scope.inputLabel.labelFilter = ''; - $scope.updateFilter(); + $scope.inputLabel.labelFilter = ''; + $scope.updateFilter(); helperItems = []; helperItemsLength = 0; angular.element( checkBoxLayer ).addClass( 'show' ); - angular.element( clickedEl ).addClass( 'buttonClicked' ); + angular.element( clickedEl ).addClass( 'buttonClicked' ); - // Attach change event listener on the input filter. - // We need this because ng-change is apparently not an event listener. + // Attach change event listener on the input filter. + // We need this because ng-change is apparently not an event listener. angular.element( document ).on( 'click', $scope.externalClickListener ); - angular.element( document ).on( 'keydown', $scope.keyboardListener ); + angular.element( document ).on( 'keydown', $scope.keyboardListener ); - // to get the initial tab index, depending on how many helper elements we have. - // priority is to always focus it on the input filter + // to get the initial tab index, depending on how many helper elements we have. + // priority is to always focus it on the input filter $scope.getFormElements(); $scope.tabIndex = 0; - var helperContainer = angular.element( element[ 0 ].querySelector( '.helperContainer' ) )[0]; - + var helperContainer = angular.element( element[ 0 ].querySelector( '.helperContainer' ) )[0]; + if ( typeof helperContainer !== 'undefined' ) { for ( var i = 0; i < helperContainer.getElementsByTagName( 'BUTTON' ).length ; i++ ) { helperItems[ i ] = helperContainer.getElementsByTagName( 'BUTTON' )[ i ]; } helperItemsLength = helperItems.length + helperContainer.getElementsByTagName( 'INPUT' ).length; } - - // focus on the filter element on open. - if ( element[ 0 ].querySelector( '.inputFilter' ) ) { - element[ 0 ].querySelector( '.inputFilter' ).focus(); + + // focus on the filter element on open. + if ( element[ 0 ].querySelector( '.inputFilter' ) ) { + element[ 0 ].querySelector( '.inputFilter' ).focus(); $scope.tabIndex = $scope.tabIndex + helperItemsLength - 2; // blur button in vain angular.element( element ).children()[ 0 ].blur(); } // if there's no filter then just focus on the first checkbox item - else { - if ( !$scope.isDisabled ) { + else { + if ( !$scope.isDisabled ) { $scope.tabIndex = $scope.tabIndex + helperItemsLength; if ( $scope.inputModel.length > 0 ) { formElements[ $scope.tabIndex ].focus(); $scope.setFocusStyle( $scope.tabIndex ); // blur button in vain angular.element( element ).children()[ 0 ].blur(); - } + } } - } + } // open callback $scope.onOpen(); - } + } } - + // handle clicks outside the button / multi select layer - $scope.externalClickListener = function( e ) { + $scope.externalClickListener = function( e ) { var targetsArr = element.find( e.target.tagName ); - for (var i = 0; i < targetsArr.length; i++) { + for (var i = 0; i < targetsArr.length; i++) { if ( e.target == targetsArr[i] ) { return; } } - angular.element( checkBoxLayer.previousSibling ).removeClass( 'buttonClicked' ); + angular.element( checkBoxLayer.previousSibling ).removeClass( 'buttonClicked' ); angular.element( checkBoxLayer ).removeClass( 'show' ); - angular.element( document ).off( 'click', $scope.externalClickListener ); - angular.element( document ).off( 'keydown', $scope.keyboardListener ); - - // close callback + angular.element( document ).off( 'click', $scope.externalClickListener ); + angular.element( document ).off( 'keydown', $scope.keyboardListener ); + + // close callback $timeout( function() { $scope.onClose(); }, 0 ); @@ -3398,7 +3411,7 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' // set focus on button again element.children().children()[ 0 ].focus(); } - + // select All / select None / reset buttons $scope.select = function( type, e ) { @@ -3407,72 +3420,72 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' switch( type.toUpperCase() ) { case 'ALL': - angular.forEach( $scope.filteredModel, function( value, key ) { - if ( typeof value !== 'undefined' && value[ attrs.disableProperty ] !== true ) { - if ( typeof value[ attrs.groupProperty ] === 'undefined' ) { + angular.forEach( $scope.filteredModel, function( value, key ) { + if ( typeof value !== 'undefined' && value[ attrs.disableProperty ] !== true ) { + if ( typeof value[ attrs.groupProperty ] === 'undefined' ) { value[ $scope.tickProperty ] = true; } } - }); - $scope.refreshOutputModel(); - $scope.refreshButton(); - $scope.onSelectAll(); + }); + $scope.refreshOutputModel(); + $scope.refreshButton(); + $scope.onSelectAll(); break; case 'NONE': angular.forEach( $scope.filteredModel, function( value, key ) { - if ( typeof value !== 'undefined' && value[ attrs.disableProperty ] !== true ) { - if ( typeof value[ attrs.groupProperty ] === 'undefined' ) { + if ( typeof value !== 'undefined' && value[ attrs.disableProperty ] !== true ) { + if ( typeof value[ attrs.groupProperty ] === 'undefined' ) { value[ $scope.tickProperty ] = false; } } - }); - $scope.refreshOutputModel(); - $scope.refreshButton(); - $scope.onSelectNone(); + }); + $scope.refreshOutputModel(); + $scope.refreshButton(); + $scope.onSelectNone(); break; - case 'RESET': - angular.forEach( $scope.filteredModel, function( value, key ) { - if ( typeof value[ attrs.groupProperty ] === 'undefined' && typeof value !== 'undefined' && value[ attrs.disableProperty ] !== true ) { - var temp = value[ $scope.indexProperty ]; + case 'RESET': + angular.forEach( $scope.filteredModel, function( value, key ) { + if ( typeof value[ attrs.groupProperty ] === 'undefined' && typeof value !== 'undefined' && value[ attrs.disableProperty ] !== true ) { + var temp = value[ $scope.indexProperty ]; value[ $scope.tickProperty ] = $scope.backUp[ temp ][ $scope.tickProperty ]; } - }); - $scope.refreshOutputModel(); - $scope.refreshButton(); - $scope.onReset(); + }); + $scope.refreshOutputModel(); + $scope.refreshButton(); + $scope.onReset(); break; case 'CLEAR': $scope.tabIndex = $scope.tabIndex + 1; - $scope.onClear(); + $scope.onClear(); break; - case 'FILTER': + case 'FILTER': $scope.tabIndex = helperItems.length - 1; break; - default: - } - } + default: + } + } - // just to create a random variable name - function genRandomString( length ) { + // just to create a random variable name + function genRandomString( length ) { var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; var temp = ''; for( var i=0; i < length; i++ ) { - temp += possible.charAt( Math.floor( Math.random() * possible.length )); + temp += possible.charAt( Math.floor( Math.random() * possible.length )); } return temp; } // count leading spaces $scope.prepareGrouping = function() { - var spacing = 0; + var spacing = 0; angular.forEach( $scope.filteredModel, function( value, key ) { - value[ $scope.spacingProperty ] = spacing; + value[ $scope.spacingProperty ] = spacing; if ( value[ attrs.groupProperty ] === true ) { spacing+=2; - } + } else if ( value[ attrs.groupProperty ] === false ) { spacing-=2; - } + } }); } @@ -3486,94 +3499,94 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' } // navigate using up and down arrow - $scope.keyboardListener = function( e ) { - - var key = e.keyCode ? e.keyCode : e.which; - var isNavigationKey = false; + $scope.keyboardListener = function( e ) { + + var key = e.keyCode ? e.keyCode : e.which; + var isNavigationKey = false; // ESC key (close) if ( key === 27 ) { - e.preventDefault(); + e.preventDefault(); e.stopPropagation(); $scope.toggleCheckboxes( e ); - } - - - // next element ( tab, down & right key ) - else if ( key === 40 || key === 39 || ( !e.shiftKey && key == 9 ) ) { - + } + + + // next element ( tab, down & right key ) + else if ( key === 40 || key === 39 || ( !e.shiftKey && key == 9 ) ) { + isNavigationKey = true; - prevTabIndex = $scope.tabIndex; - $scope.tabIndex++; + prevTabIndex = $scope.tabIndex; + $scope.tabIndex++; if ( $scope.tabIndex > formElements.length - 1 ) { $scope.tabIndex = 0; - prevTabIndex = formElements.length - 1; - } + prevTabIndex = formElements.length - 1; + } while ( formElements[ $scope.tabIndex ].disabled === true ) { $scope.tabIndex++; if ( $scope.tabIndex > formElements.length - 1 ) { - $scope.tabIndex = 0; - } + $scope.tabIndex = 0; + } if ( $scope.tabIndex === prevTabIndex ) { break; } - } + } } - + // prev element ( shift+tab, up & left key ) - else if ( key === 38 || key === 37 || ( e.shiftKey && key == 9 ) ) { + else if ( key === 38 || key === 37 || ( e.shiftKey && key == 9 ) ) { isNavigationKey = true; - prevTabIndex = $scope.tabIndex; - $scope.tabIndex--; + prevTabIndex = $scope.tabIndex; + $scope.tabIndex--; if ( $scope.tabIndex < 0 ) { $scope.tabIndex = formElements.length - 1; prevTabIndex = 0; - } - while ( formElements[ $scope.tabIndex ].disabled === true ) { + } + while ( formElements[ $scope.tabIndex ].disabled === true ) { $scope.tabIndex--; if ( $scope.tabIndex === prevTabIndex ) { break; - } + } if ( $scope.tabIndex < 0 ) { $scope.tabIndex = formElements.length - 1; - } - } - } - - if ( isNavigationKey === true ) { + } + } + } + if ( isNavigationKey === true ) { + e.preventDefault(); - // set focus on the checkbox - formElements[ $scope.tabIndex ].focus(); - var actEl = document.activeElement; - - if ( actEl.type.toUpperCase() === 'CHECKBOX' ) { + // set focus on the checkbox + formElements[ $scope.tabIndex ].focus(); + var actEl = document.activeElement; + + if ( actEl.type.toUpperCase() === 'CHECKBOX' ) { $scope.setFocusStyle( $scope.tabIndex ); $scope.removeFocusStyle( prevTabIndex ); - } + } else { $scope.removeFocusStyle( prevTabIndex ); $scope.removeFocusStyle( helperItemsLength ); $scope.removeFocusStyle( formElements.length - 1 ); - } - } + } + } isNavigationKey = false; } // set (add) CSS style on selected row - $scope.setFocusStyle = function( tabIndex ) { - angular.element( formElements[ tabIndex ] ).parent().parent().parent().addClass( 'multiSelectFocus' ); + $scope.setFocusStyle = function( tabIndex ) { + angular.element( formElements[ tabIndex ] ).parent().parent().parent().addClass( 'multiSelectFocus' ); } // remove CSS style on selected row - $scope.removeFocusStyle = function( tabIndex ) { + $scope.removeFocusStyle = function( tabIndex ) { angular.element( formElements[ tabIndex ] ).parent().parent().parent().removeClass( 'multiSelectFocus' ); } /********************* - ********************* + ********************* * * 1) Initializations * @@ -3582,44 +3595,44 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' // attrs to $scope - attrs-$scope - attrs - $scope // Copy some properties that will be used on the template. They need to be in the $scope. - $scope.groupProperty = attrs.groupProperty; + $scope.groupProperty = attrs.groupProperty; $scope.tickProperty = attrs.tickProperty; $scope.directiveId = attrs.directiveId; - + // Unfortunately I need to add these grouping properties into the input model var tempStr = genRandomString( 5 ); $scope.indexProperty = 'idx_' + tempStr; - $scope.spacingProperty = 'spc_' + tempStr; + $scope.spacingProperty = 'spc_' + tempStr; - // set orientation css + // set orientation css if ( typeof attrs.orientation !== 'undefined' ) { - if ( attrs.orientation.toUpperCase() === 'HORIZONTAL' ) { + if ( attrs.orientation.toUpperCase() === 'HORIZONTAL' ) { $scope.orientationH = true; $scope.orientationV = false; } - else + else { $scope.orientationH = false; $scope.orientationV = true; } - } + } // get elements required for DOM operation checkBoxLayer = element.children().children().next()[0]; // set max-height property if provided - if ( typeof attrs.maxHeight !== 'undefined' ) { + if ( typeof attrs.maxHeight !== 'undefined' ) { var layer = element.children().children().children()[0]; - angular.element( layer ).attr( "style", "height:" + attrs.maxHeight + "; overflow-y:scroll;" ); + angular.element( layer ).attr( "style", "height:" + attrs.maxHeight + "; overflow-y:scroll;" ); } - // some flags for easier checking + // some flags for easier checking for ( var property in $scope.helperStatus ) { - if ( $scope.helperStatus.hasOwnProperty( property )) { - if ( - typeof attrs.helperElements !== 'undefined' - && attrs.helperElements.toUpperCase().indexOf( property.toUpperCase() ) === -1 + if ( $scope.helperStatus.hasOwnProperty( property )) { + if ( + typeof attrs.helperElements !== 'undefined' + && attrs.helperElements.toUpperCase().indexOf( property.toUpperCase() ) === -1 ) { $scope.helperStatus[ property ] = false; } @@ -3630,31 +3643,31 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' $scope.helperStatus[ 'none' ] = false; } - // helper button icons.. I guess you can use html tag here if you want to. - $scope.icon = {}; + // helper button icons.. I guess you can use html tag here if you want to. + $scope.icon = {}; $scope.icon.selectAll = '✓'; // a tick icon $scope.icon.selectNone = '×'; // x icon - $scope.icon.reset = '↶'; // undo icon + $scope.icon.reset = '↶'; // undo icon // this one is for the selected items - $scope.icon.tickMark = '✓'; // a tick icon + $scope.icon.tickMark = '✓'; // a tick icon - // configurable button labels + // configurable button labels if ( typeof attrs.translation !== 'undefined' ) { $scope.lang.selectAll = $sce.trustAsHtml( $scope.icon.selectAll + '  ' + $scope.translation.selectAll ); $scope.lang.selectNone = $sce.trustAsHtml( $scope.icon.selectNone + '  ' + $scope.translation.selectNone ); $scope.lang.reset = $sce.trustAsHtml( $scope.icon.reset + '  ' + $scope.translation.reset ); - $scope.lang.search = $scope.translation.search; - $scope.lang.nothingSelected = $sce.trustAsHtml( $scope.translation.nothingSelected ); + $scope.lang.search = $scope.translation.search; + $scope.lang.nothingSelected = $sce.trustAsHtml( $scope.translation.nothingSelected ); } else { - $scope.lang.selectAll = $sce.trustAsHtml( $scope.icon.selectAll + '  Select All' ); + $scope.lang.selectAll = $sce.trustAsHtml( $scope.icon.selectAll + '  Select All' ); $scope.lang.selectNone = $sce.trustAsHtml( $scope.icon.selectNone + '  Select None' ); $scope.lang.reset = $sce.trustAsHtml( $scope.icon.reset + '  Reset' ); $scope.lang.search = 'Search...'; - $scope.lang.nothingSelected = 'None Selected'; + $scope.lang.nothingSelected = 'None Selected'; } $scope.icon.tickMark = $sce.trustAsHtml( $scope.icon.tickMark ); - + // min length of keyword to trigger the filter function if ( typeof attrs.MinSearchLength !== 'undefined' && parseInt( attrs.MinSearchLength ) > 0 ) { vMinSearchLength = Math.floor( parseInt( attrs.MinSearchLength ) ); @@ -3667,147 +3680,147 @@ angular.module( 'isteven-multi-select', ['ng'] ).directive( 'istevenMultiSelect' * ******************************************************* *******************************************************/ - + // watch1, for changes in input model property // updates multi-select when user select/deselect a single checkbox programatically - // https://github.com/isteven/angular-multi-select/issues/8 - $scope.$watch( 'inputModel' , function( newVal ) { - if ( newVal ) { - $scope.refreshOutputModel(); - $scope.refreshButton(); + // https://github.com/isteven/angular-multi-select/issues/8 + $scope.$watch( 'inputModel' , function( newVal ) { + if ( newVal ) { + $scope.refreshOutputModel(); + $scope.refreshButton(); } }, true ); - + // watch2 for changes in input model as a whole // this on updates the multi-select when a user load a whole new input-model. We also update the $scope.backUp variable - $scope.$watch( 'inputModel' , function( newVal ) { + $scope.$watch( 'inputModel' , function( newVal ) { if ( newVal ) { - $scope.backUp = angular.copy( $scope.inputModel ); + $scope.backUp = angular.copy( $scope.inputModel ); $scope.updateFilter(); $scope.prepareGrouping(); - $scope.prepareIndex(); - $scope.refreshOutputModel(); - $scope.refreshButton(); + $scope.prepareIndex(); + $scope.refreshOutputModel(); + $scope.refreshButton(); } - }); + }); // watch for changes in directive state (disabled or enabled) - $scope.$watch( 'isDisabled' , function( newVal ) { - $scope.isDisabled = newVal; - }); - - // this is for touch enabled devices. We don't want to hide checkboxes on scroll. - var onTouchStart = function( e ) { - $scope.$apply( function() { - $scope.scrolled = false; - }); + $scope.$watch( 'isDisabled' , function( newVal ) { + $scope.isDisabled = newVal; + }); + + // this is for touch enabled devices. We don't want to hide checkboxes on scroll. + var onTouchStart = function( e ) { + $scope.$apply( function() { + $scope.scrolled = false; + }); }; angular.element( document ).bind( 'touchstart', onTouchStart); - var onTouchMove = function( e ) { - $scope.$apply( function() { - $scope.scrolled = true; - }); + var onTouchMove = function( e ) { + $scope.$apply( function() { + $scope.scrolled = true; + }); }; - angular.element( document ).bind( 'touchmove', onTouchMove); + angular.element( document ).bind( 'touchmove', onTouchMove); // unbind document events to prevent memory leaks $scope.$on( '$destroy', function () { - angular.element( document ).unbind( 'touchstart', onTouchStart); - angular.element( document ).unbind( 'touchmove', onTouchMove); + angular.element( document ).unbind( 'touchstart', onTouchStart); + angular.element( document ).unbind( 'touchmove', onTouchMove); }); } } }]).run( [ '$templateCache' , function( $templateCache ) { - var template = + var template = '' + - // main button - '' + - // overlay layer - '
' + - // container of the helper elements - '
' + - // container of the first 3 buttons, select all, none and reset - '
' + - // select all - ''+ - // select none - ''+ - // reset - '' + - '
' + - // the search box - '
'+ - // textfield - ''+ - // clear button - ' '+ - '
'+ - '
'+ - // selection items - '
'+ - '
'+ - // this is the spacing for grouped items - '
'+ - '
'+ - '
'+ - ''+ - '
'+ - // the tick/check mark - ''+ - '
'+ - '
'+ + // main button + '' + + // overlay layer + '
' + + // container of the helper elements + '
' + + // container of the first 3 buttons, select all, none and reset + '
' + + // select all + ''+ + // select none + ''+ + // reset + '' + + '
' + + // the search box + '
'+ + // textfield + ''+ + // clear button + ' '+ + '
'+ + '
'+ + // selection items + '
'+ + '
'+ + // this is the spacing for grouped items + '
'+ + '
'+ + '
'+ + ''+ + '
'+ + // the tick/check mark + ''+ + '
'+ + '
'+ '
'+ - ''; - $templateCache.put( 'isteven-multi-select.htm' , template ); -}]); + ''; + $templateCache.put( 'isteven-multi-select.htm' , template ); +}]); angular.module("FileManagerApp").run(["$templateCache", function($templateCache) {$templateCache.put("src/templates/current-folder-breadcrumb.html","
    \n
  1. \n \n {{ config.appName }}\n \n
  2. \n
  3. \n \n {{dir | strLimit : 8}}\n \n \n {{dir | strLimit : 12}}\n \n
  4. \n
"); - $templateCache.put("src/templates/item-context-menu.html",""); - $templateCache.put("src/templates/main-icons-preview.html","
\n \n\n
\n
\n
\n\n
\n {{\"no_files_in_folder\" | translate}}...\n
\n \n
\n {{ fileNavigator.error }}\n
\n
"); - $templateCache.put("src/templates/main-icons.html","
\n \n\n
\n
\n
\n\n
\n {{\"no_files_in_folder\" | translate}}...\n
\n \n
\n {{ fileNavigator.error }}\n
\n
"); - $templateCache.put("src/templates/main-table-modal.html","\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{\"name\" | translate}}\n \n \n
\n
\n
\n {{\"no_folders_in_folder\" | translate}}...\n \n \n
\n {{ fileNavigator.error }}\n
\n \n \n {{item.model.name | strLimit : 32}}\n \n \n \n
"); - $templateCache.put("src/templates/main-table.html","\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{\"name\" | translate}}\n \n \n \n \n {{\"size\" | translate}}\n \n \n \n \n {{\"date\" | translate}}\n \n \n \n \n {{\"permissions\" | translate}}\n \n \n
\n
\n
\n {{\"no_files_in_folder\" | translate}}...\n
\n {{ fileNavigator.error }}\n
\n \n \n \n {{item.model.name | strLimit : 64}}\n \n \n \n {{item.model.size | humanReadableFileSize}}\n \n \n {{item.model.date | formatDate }}\n \n {{item.model.perms.toCode(item.model.type === \'dir\'?\'d\':\'-\')}}\n
\n"); - $templateCache.put("src/templates/main.html","
\n
\n\n
\n
\n\n
\n
\n\n
\n
\n
\n
\n
\n\n
\n
\n
\n"); - $templateCache.put("src/templates/modals.html","
\n
\n
\n
\n \n

{{\"preview\" | translate}}

\n
\n
\n
\n\n \"{{singleSelection().model.name}}\"\n {{\'loading\' | translate}} ...\n
\n
\n
\n
\n \n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\"confirm\" | translate}}

\n
\n
\n {{\'sure_to_delete\' | translate}} \n\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'move\' | translate}}

\n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n\n
\n
\n
\n
\n
\n \n

{{\'rename\' | translate}}

\n
\n
\n \n \n\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'copy_file\' | translate}}

\n
\n
\n
\n \n \n
\n\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'compress\' | translate}}

\n
\n
\n
\n
{{\'compression_started\' | translate}}
\n
\n
\n
\n {{\'sure_to_start_compression_with\' | translate}} {{singleSelection().model.name}} ?\n
\n
\n \n \n
\n
\n\n
\n
\n
\n
\n \n
\n
\n \n \n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'extract_item\' | translate}}

\n
\n
\n
\n
{{\'extraction_started\' | translate}}
\n
\n
\n \n \n
\n
\n
\n
\n
\n \n
\n
\n \n \n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n \n

{{\'edit_file\' | translate}}

\n
\n
\n \n {{\'loading\' | translate}} ...\n \n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'new_folder\' | translate}}

\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\"upload_files\" | translate}}

\n
\n
\n \n \n\n
\n
    \n
  • \n \n
    {{uploadFile.name}}
    \n

    {{uploadFile.size | humanReadableFileSize}}

    \n
  • \n
\n
\n {{\"uploading\" | translate}}... {{apiMiddleware.apiHandler.progress}}%\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n \n
\n \n

{{\'change_permissions\' | translate}}

\n
\n
\n
\n
\n

{{\'read\' | translate}}

\n \n
\n
\n
\n
\n
\n
\n

{{\'write\' | translate}}

\n\n \n
\n
\n
\n
\n
\n
\n

{{\'delete\' | translate}}

\n \n
\n
\n
\n
\n
\n
\n
\n \n \n
\n \n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'copy_links\' | translate}}

\n
\n
\n\n \n\n
\n \n \n \n \n
\n\n \n\n
\n \n \n \n \n
\n\n \n\n
\n \n \n \n \n
\n\n
\n
\n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n \n

{{\"select_destination_folder\" | translate}}

\n
\n
\n
\n
\n
\n
\n \n
\n
\n
\n \n
\n
\n
\n
\n\n\n\n\n\n\n"); - $templateCache.put("src/templates/navbar.html",""); - $templateCache.put("src/templates/sidebar.html","\n\n"); - $templateCache.put("src/templates/spinner.html","
\n \n \n \n
");}]); \ No newline at end of file +$templateCache.put("src/templates/item-context-menu.html",""); +$templateCache.put("src/templates/main-icons-preview.html","
\n \n\n
\n
\n
\n\n
\n {{\"no_files_in_folder\" | translate}}...\n
\n \n
\n {{ fileNavigator.error }}\n
\n
"); +$templateCache.put("src/templates/main-icons.html","
\n \n\n
\n
\n
\n\n
\n {{\"no_files_in_folder\" | translate}}...\n
\n \n
\n {{ fileNavigator.error }}\n
\n
"); +$templateCache.put("src/templates/main-table-modal.html","\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{\"name\" | translate}}\n \n \n
\n
\n
\n {{\"no_folders_in_folder\" | translate}}...\n \n \n
\n {{ fileNavigator.error }}\n
\n \n \n {{item.model.name | strLimit : 32}}\n \n \n \n
"); +$templateCache.put("src/templates/main-table.html","\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{\"name\" | translate}}\n \n \n \n \n {{\"size\" | translate}}\n \n \n \n \n {{\"date\" | translate}}\n \n \n \n \n {{\"permissions\" | translate}}\n \n \n
\n
\n
\n {{\"no_files_in_folder\" | translate}}...\n
\n {{ fileNavigator.error }}\n
\n \n \n \n {{item.model.name | strLimit : 64}}\n \n \n \n {{item.model.size | humanReadableFileSize}}\n \n \n {{item.model.date | formatDate }}\n \n {{item.model.perms.toCode(item.model.type === \'dir\'?\'d\':\'-\')}}\n
\n"); +$templateCache.put("src/templates/main.html","
\n
\n\n
\n
\n\n
\n
\n\n
\n
\n
\n
\n
\n\n
\n
\n
\n"); +$templateCache.put("src/templates/modals.html","
\n
\n
\n
\n \n

{{\"preview\" | translate}}

\n
\n
\n
\n\n \"{{singleSelection().model.name}}\"\n {{\'loading\' | translate}} ...\n
\n
\n
\n
\n \n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\"confirm\" | translate}}

\n
\n
\n {{\'sure_to_delete\' | translate}} \n\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'move\' | translate}}

\n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n\n
\n
\n
\n
\n
\n \n

{{\'rename\' | translate}}

\n
\n
\n \n \n\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'copy_file\' | translate}}

\n
\n
\n
\n \n \n
\n\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'compress\' | translate}}

\n
\n
\n
\n
{{\'compression_started\' | translate}}
\n
\n
\n
\n {{\'sure_to_start_compression_with\' | translate}} {{singleSelection().model.name}} ?\n
\n
\n \n \n
\n
\n\n
\n
\n
\n
\n \n
\n
\n \n \n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'extract_item\' | translate}}

\n
\n
\n
\n
{{\'extraction_started\' | translate}}
\n
\n
\n \n \n
\n
\n
\n
\n
\n \n
\n
\n \n \n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n \n

{{\'edit_file\' | translate}}

\n
\n
\n \n {{\'loading\' | translate}} ...\n \n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'new_folder\' | translate}}

\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\"upload_files\" | translate}}

\n
\n
\n \n \n\n
\n
    \n
  • \n \n
    {{uploadFile.name}}
    \n

    {{uploadFile.size | humanReadableFileSize}}

    \n
  • \n
\n
\n {{\"uploading\" | translate}}... {{apiMiddleware.apiHandler.progress}}%\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n \n
\n \n

{{\'change_permissions\' | translate}}

\n
\n
\n
\n
\n

{{\'read\' | translate}}

\n \n
\n
\n
\n
\n
\n
\n

{{\'write\' | translate}}

\n\n \n
\n
\n
\n
\n
\n
\n

{{\'delete\' | translate}}

\n \n
\n
\n
\n
\n
\n
\n
\n \n \n
\n \n \n \n\n\n
\n
\n
\n
\n
\n \n

{{\'copy_links\' | translate}}

\n
\n
\n\n \n\n
\n \n \n \n \n
\n\n \n\n
\n \n \n \n \n
\n\n \n\n
\n \n \n \n \n
\n\n
\n
\n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n \n

{{\"select_destination_folder\" | translate}}

\n
\n
\n
\n
\n
\n
\n \n
\n
\n
\n \n
\n
\n
\n
\n\n\n\n\n\n\n"); +$templateCache.put("src/templates/navbar.html",""); +$templateCache.put("src/templates/sidebar.html","\n\n"); +$templateCache.put("src/templates/spinner.html","
\n \n \n \n
");}]); \ No newline at end of file diff --git a/src/widgets/FileManagerWidget.php b/src/widgets/FileManagerWidget.php index f223e4e..8261fe6 100644 --- a/src/widgets/FileManagerWidget.php +++ b/src/widgets/FileManagerWidget.php @@ -49,6 +49,15 @@ class FileManagerWidget extends Widget */ public $thumbnailUrlSuffix; + /** + * @var boolean + */ + public $enableThumbnails; + + /** + * @var boolean + */ + public $enableIconPreviewView; /** * @inheritdoc */ @@ -142,6 +151,8 @@ protected function setFileManagerConfig() enablePermissionsRecursive: false, thumbnailUrlPrefix: '{$this->thumbnailUrlPrefix}', thumbnailUrlSuffix: '{$this->thumbnailUrlSuffix}', + enableThumbnails: {$this->enableThumbnails}, + enableIconPreviewView: {$this->enableIconPreviewView}, // File patterns isEditableFilePattern: /\.(!)/i, From 41c28eed86bc916cccf1cb2910554c364b62a0f8 Mon Sep 17 00:00:00 2001 From: amk Date: Mon, 7 Sep 2020 10:47:03 +0200 Subject: [PATCH 3/4] updated filemanager.js --- src/assets/dist/angular-filemanager.min.js | 3827 +++++++++++++++++++- 1 file changed, 3826 insertions(+), 1 deletion(-) mode change 100644 => 100755 src/assets/dist/angular-filemanager.min.js diff --git a/src/assets/dist/angular-filemanager.min.js b/src/assets/dist/angular-filemanager.min.js old mode 100644 new mode 100755 index ae1d1e6..d9c2f7f --- a/src/assets/dist/angular-filemanager.min.js +++ b/src/assets/dist/angular-filemanager.min.js @@ -1 +1,3826 @@ -!function(e,n,t){"use strict";n.module("FileManagerApp",["pascalprecht.translate","ngFileUpload","ngSanitize","isteven-multi-select","ngclipboard"]),t(e.document).on("shown.bs.modal",".modal",function(){e.setTimeout(function(){t("[autofocus]",this).focus()}.bind(this),100)}),t(e.document).on("click",function(){t("#context-menu").hide()}),t(e.document).on("contextmenu",'.main-navigation .table-files tr.item-list:has("td"), .item-list',function(e){var n=t("#context-menu"),r=n.width(),i=n.parent().parent().offset(),a=e.pageX-i.left;a>=window.innerWidth-r&&(a-=r),n.hide().css({position:"fixed",left:a,top:e.pageY-i.top}).show(),e.preventDefault()}),Array.prototype.find||(Array.prototype.find=function(e){if(null==this)throw new TypeError("Array.prototype.find called on null or undefined");if("function"!=typeof e)throw new TypeError("predicate must be a function");for(var n,t=Object(this),r=t.length>>>0,i=arguments[1],a=0;r>a;a++)if(n=t[a],e.call(i,n,a,t))return n})}(window,angular,jQuery),function(e,n){"use strict";e.module("FileManagerApp").controller("FileManagerCtrl",["$scope","$rootScope","$window","$translate","$http","fileManagerConfig","item","fileNavigator","apiMiddleware",function(e,t,r,i,a,o,l,s,d){var c=r.localStorage;e.config=o,e.reverse=!1,e.predicate=["model.type","model.name"],e.order=function(n){e.reverse=e.predicate[1]===n?!e.reverse:!1,e.predicate[1]=n},e.query="",e.fileNavigator=new s,e.apiMiddleware=new d,e.uploadFileList=[],e.viewTemplate=c.getItem("viewTemplate")||"main-icons.html",e.fileList=[],e.temps=[],e.$watch("temps",function(){e.singleSelection()?e.temp=e.singleSelection():(e.temp=new l({rights:644}),e.temp.multiple=!0),e.temp.revert()}),e.fileNavigator.onRefresh=function(){e.temps=[],e.query="",t.selectedModalPath=e.fileNavigator.currentPath},e.setTemplate=function(n){c.setItem("viewTemplate",n),e.viewTemplate=n},e.changeLanguage=function(e){return e?(c.setItem("language",e),i.use(e)):void i.use(c.getItem("language")||o.defaultLang)},e.isSelected=function(n){return-1!==e.temps.indexOf(n)},e.selectOrUnselect=function(n,t){var r=e.temps.indexOf(n),i=t&&3==t.which;if(t&&t.target.hasAttribute("prevent"))return void(e.temps=[]);if(!(!n||i&&e.isSelected(n))){if(t&&t.shiftKey&&!i){var a=e.fileList,o=a.indexOf(n),l=e.temps[0],s=a.indexOf(l),d=void 0;if(l&&a.indexOf(l)=s;)d=a[s],!e.isSelected(d)&&e.temps.push(d),s++;return}if(l&&a.indexOf(l)>o){for(e.temps=[];s>=o;)d=a[s],!e.isSelected(d)&&e.temps.push(d),s--;return}}return t&&!i&&(t.ctrlKey||t.metaKey)?void(e.isSelected(n)?e.temps.splice(r,1):e.temps.push(n)):void(e.temps=[n])}},e.singleSelection=function(){return 1===e.temps.length&&e.temps[0]},e.totalSelecteds=function(){return{total:e.temps.length}},e.selectionHas=function(n){return e.temps.find(function(e){return e&&e.model.type===n})},e.prepareNewFolder=function(){var n=new l(null,e.fileNavigator.currentPath);return e.temps=[n],n},e.smartClick=function(n){var t=e.config.allowedActions.pickFiles;if(n.isFolder())return e.fileNavigator.folderClick(n);if("function"==typeof e.config.pickCallback&&t){var r=e.config.pickCallback(n.model);if(r===!0)return}return n.isImage()?e.config.previewImagesInModal?e.openImagePreview(n):e.apiMiddleware.download(n,!0):n.isEditable()?e.openEditItem(n):void 0},e.openImagePreview=function(){var n=e.singleSelection();e.apiMiddleware.apiHandler.inprocess=!0,e.modal("imagepreview",null,!0).find("#imagepreview-target").attr("src",e.apiMiddleware.getUrl(n)).unbind("load error").on("load error",function(){e.apiMiddleware.apiHandler.inprocess=!1,e.$apply()})},e.openEditItem=function(){var n=e.singleSelection();e.apiMiddleware.getContent(n).then(function(e){n.tempModel.content=n.model.content=e.result}),e.modal("edit")},e.modal=function(t,r,i){var a=n("#"+t);return a.modal(r?"hide":"show"),e.apiMiddleware.apiHandler.error="",e.apiMiddleware.apiHandler.asyncSuccess=!1,i?a:!0},e.modalWithPathSelector=function(n){return t.selectedModalPath=e.fileNavigator.currentPath,e.modal(n)},e.isInThisPath=function(n){var t=e.fileNavigator.currentPath.join("/");return-1!==t.indexOf(n)},e.edit=function(){e.apiMiddleware.edit(e.singleSelection()).then(function(){e.modal("edit",!0)})},e.updatePermissions=function(){var n=e.singleSelection(),t=o.permissionsUrl,r={action:"resolvePermissions",path:n.model.fullPath()};a.post(t,r).success(function(e){n.model.authRead=e.auth.read,n.model.authUpdate=e.auth.update,n.model.authDelete=e.auth["delete"]}).error(function(){e.apiMiddleware.apiHandler.error=i.instant("error_get_permissions")})["finally"](function(){e.modal("changepermissions",!1)})},e.changePermissions=function(n,t,r){var i=e.singleSelection();e.apiMiddleware.changePermissions(i.tempModel).then(function(){e.modal("changepermissions",!0)})},e.rename=function(){var n=e.singleSelection(),t=n.tempModel.name,r=n.tempModel.path.join("")===n.model.path.join("");return!t||r&&e.fileNavigator.fileNameExists(t)?(e.apiMiddleware.apiHandler.error=i.instant("error_invalid_filename"),!1):void e.apiMiddleware.rename(n).then(function(){e.fileNavigator.refresh(),e.modal("rename",!0)})},e.refreshLocation=function(n){e.fileNavigator.refresh(n)},e.downloadLink=function(){var t=e.singleSelection();if(!e.selectionHas("dir")){var r=t.model.fullPath(),i={action:"download",path:r},a={action:"stream",path:r},l=window.location.protocol+"//"+window.location.host,s=[o.downloadFileUrl,n.param(i)].join("?"),d=[o.downloadFileUrl,n.param(a)].join("?");e.dlLink=l+s,e.streamLink=d,e.path=r,e.modal("downloadlink",!1)}},e.download=function(){var n=e.singleSelection();if(!e.selectionHas("dir"))return n?e.apiMiddleware.download(n):e.apiMiddleware.downloadMultiple(e.temps)},e.copy=function(){var n=e.singleSelection();if(n){var r=n.tempModel.name.trim(),a=e.fileNavigator.fileNameExists(r);if(a&&p(n))return e.apiMiddleware.apiHandler.error=i.instant("error_invalid_filename"),!1;if(!r)return e.apiMiddleware.apiHandler.error=i.instant("error_invalid_filename"),!1}e.apiMiddleware.copy(e.temps,t.selectedModalPath).then(function(){e.fileNavigator.refresh(),e.modal("copy",!0)})},e.compress=function(){var n=e.temp.tempModel.name.trim(),r=e.fileNavigator.fileNameExists(n);return r&&p(e.temp)?(e.apiMiddleware.apiHandler.error=i.instant("error_invalid_filename"),!1):n?void e.apiMiddleware.compress(e.temps,n,t.selectedModalPath).then(function(){return e.fileNavigator.refresh(),e.config.compressAsync?void(e.apiMiddleware.apiHandler.asyncSuccess=!0):e.modal("compress",!0)},function(){e.apiMiddleware.apiHandler.asyncSuccess=!1}):(e.apiMiddleware.apiHandler.error=i.instant("error_invalid_filename"),!1)},e.extract=function(){var n=e.temp,r=e.temp.tempModel.name.trim(),a=e.fileNavigator.fileNameExists(r);return a&&p(e.temp)?(e.apiMiddleware.apiHandler.error=i.instant("error_invalid_filename"),!1):r?void e.apiMiddleware.extract(n,r,t.selectedModalPath).then(function(){return e.fileNavigator.refresh(),e.config.extractAsync?void(e.apiMiddleware.apiHandler.asyncSuccess=!0):e.modal("extract",!0)},function(){e.apiMiddleware.apiHandler.asyncSuccess=!1}):(e.apiMiddleware.apiHandler.error=i.instant("error_invalid_filename"),!1)},e.remove=function(){e.apiMiddleware.remove(e.temps).then(function(){e.fileNavigator.refresh(),e.modal("remove",!0)})},e.move=function(){var n=e.singleSelection()||e.temps[0];return n&&p(n)?(e.apiMiddleware.apiHandler.error=i.instant("error_cannot_move_same_path"),!1):void e.apiMiddleware.move(e.temps,t.selectedModalPath).then(function(){e.fileNavigator.refresh(),e.modal("move",!0)})},e.createFolder=function(){var n=e.singleSelection(),t=n.tempModel.name;return!t||e.fileNavigator.fileNameExists(t)?e.apiMiddleware.apiHandler.error=i.instant("error_invalid_filename"):void e.apiMiddleware.createFolder(n).then(function(){e.fileNavigator.refresh(),e.modal("newfolder",!0)})},e.addForUpload=function(n){e.uploadFileList=e.uploadFileList.concat(n),e.modal("uploadfile")},e.removeFromUpload=function(n){e.uploadFileList.splice(n,1)},e.uploadFiles=function(){e.apiMiddleware.upload(e.uploadFileList,e.fileNavigator.currentPath).then(function(){e.fileNavigator.refresh(),e.uploadFileList=[],e.modal("uploadfile",!0)},function(n){var t=n.result&&n.result.error||i.instant("error_uploading_files");e.apiMiddleware.apiHandler.error=t})};var p=function(e){var n=t.selectedModalPath.join(""),r=e&&e.model.path.join("");return r===n},u=function(e){var n=r.location.search.substr(1).split("&").filter(function(n){return e===n.split("=")[0]});return n[0]&&n[0].split("=")[1]||void 0};e.changeLanguage(u("lang")),e.isWindows="Windows"===u("server"),e.fileNavigator.refresh()}])}(angular,jQuery),function(e){"use strict";e.module("FileManagerApp").controller("ModalFileManagerCtrl",["$scope","$rootScope","fileNavigator",function(e,n,t){e.reverse=!1,e.predicate=["model.type","model.name"],e.fileNavigator=new t,n.selectedModalPath=[],e.order=function(n){e.reverse=e.predicate[1]===n?!e.reverse:!1,e.predicate[1]=n},e.select=function(t){n.selectedModalPath=t.model.fullPath().split("/"),e.modal("selector",!0)},e.selectCurrent=function(){n.selectedModalPath=e.fileNavigator.currentPath,e.modal("selector",!0)},e.selectedFilesAreChildOfPath=function(n){var t=n.model.fullPath();return e.temps.find(function(e){var n=e.model.fullPath();return t==n?!0:void 0})},n.openNavigator=function(n){e.fileNavigator.currentPath=n,e.fileNavigator.refresh(),e.modal("selector")},n.getSelectedPath=function(){var t=n.selectedModalPath.filter(Boolean),r="/"+t.join("/");return e.singleSelection()&&!e.singleSelection().isFolder()&&(r+="/"+e.singleSelection().tempModel.name),r.replace(/\/\//,"/")}}])}(angular),function(e){"use strict";var n=e.module("FileManagerApp");n.directive("angularFilemanager",["$parse","fileManagerConfig",function(e,n){return{restrict:"EA",templateUrl:n.tplPath+"/main.html"}}]),n.directive("ngFile",["$parse",function(e){return{restrict:"A",link:function(n,t,r){var i=e(r.ngFile),a=i.assign;t.bind("change",function(){n.$apply(function(){a(n,t[0].files)})})}}}]),n.directive("ngRightClick",["$parse",function(e){return function(n,t,r){var i=e(r.ngRightClick);t.bind("contextmenu",function(e){n.$apply(function(){e.preventDefault(),i(n,{$event:e})})})}}])}(angular),function(e){"use strict";e.module("FileManagerApp").service("chmod",function(){var e=function(e){if(this.owner=this.getRwxObj(),this.group=this.getRwxObj(),this.others=this.getRwxObj(),e){var n=isNaN(e)?this.convertfromCode(e):this.convertfromOctal(e);if(!n)throw new Error("Invalid chmod input data (%s)".replace("%s",e));this.owner=n.owner,this.group=n.group,this.others=n.others}};return e.prototype.toOctal=function(e,n){var t=[];return["owner","group","others"].forEach(function(e,n){t[n]=this[e].read&&this.octalValues.read||0,t[n]+=this[e].write&&this.octalValues.write||0,t[n]+=this[e].exec&&this.octalValues.exec||0}.bind(this)),(e||"")+t.join("")+(n||"")},e.prototype.toCode=function(e,n){var t=[];return["owner","group","others"].forEach(function(e,n){t[n]=this[e].read&&this.codeValues.read||"-",t[n]+=this[e].write&&this.codeValues.write||"-",t[n]+=this[e].exec&&this.codeValues.exec||"-"}.bind(this)),(e||"")+t.join("")+(n||"")},e.prototype.getRwxObj=function(){return{read:!1,write:!1,exec:!1}},e.prototype.octalValues={read:4,write:2,exec:1},e.prototype.codeValues={read:"r",write:"w",exec:"x"},e.prototype.convertfromCode=function(e){if(e=(""+e).replace(/\s/g,""),e=10===e.length?e.substr(1):e,/^[-rwxts]{9}$/.test(e)){var n=[],t=e.match(/.{1,3}/g);for(var r in t){var i=this.getRwxObj();i.read=/r/.test(t[r]),i.write=/w/.test(t[r]),i.exec=/x|t/.test(t[r]),n.push(i)}return{owner:n[0],group:n[1],others:n[2]}}},e.prototype.convertfromOctal=function(e){if(e=(""+e).replace(/\s/g,""),e=4===e.length?e.substr(1):e,/^[0-7]{3}$/.test(e)){var n=[],t=e.match(/.{1}/g);for(var r in t){var i=this.getRwxObj();i.read=/[4567]/.test(t[r]),i.write=/[2367]/.test(t[r]),i.exec=/[1357]/.test(t[r]),n.push(i)}return{owner:n[0],group:n[1],others:n[2]}}},e})}(angular),function(e){"use strict";e.module("FileManagerApp").factory("item",["fileManagerConfig","chmod",function(n,t){var r=function(n,r){function i(e){var n=(e||"").toString().split(/[- :]/);return new Date(n[0],n[1]-1,n[2],n[3],n[4],n[5])}var a={name:n&&n.name||"",path:r||[],type:n&&n.type||"file",size:n&&parseInt(n.size||0),date:i(n&&n.date),perms:new t(n&&n.rights),content:n&&n.content||"",recursive:!1,fullPath:function(){var e=this.path.filter(Boolean);return("/"+e.join("/")+"/"+this.name).replace(/\/\//,"/")}};this.error="",this.processing=!1,this.model=e.copy(a),this.tempModel=e.copy(a)};return r.prototype.update=function(){e.extend(this.model,e.copy(this.tempModel))},r.prototype.revert=function(){e.extend(this.tempModel,e.copy(this.model)),this.error=""},r.prototype.isFolder=function(){return"dir"===this.model.type},r.prototype.isEditable=function(){return!this.isFolder()&&n.isEditableFilePattern.test(this.model.name)},r.prototype.isImage=function(){return n.isImageFilePattern.test(this.model.name)},r.prototype.isCompressible=function(){return this.isFolder()},r.prototype.isExtractable=function(){return!this.isFolder()&&n.isExtractableFilePattern.test(this.model.name)},r.prototype.isSelectable=function(){return this.isFolder()&&n.allowedActions.pickFolders||!this.isFolder()&&n.allowedActions.pickFiles},r}])}(angular),function(e){"use strict";var n=e.module("FileManagerApp");n.filter("strLimit",["$filter",function(e){return function(n,t,r){return n.length<=t?n:e("limitTo")(n,t)+(r||"...")}}]),n.filter("fileExtension",["$filter",function(e){return function(n){return/\./.test(n)&&e("strLimit")(n.split(".").pop(),3,"..")||""}}]),n.filter("formatDate",["$filter",function(){return function(e){return e instanceof Date?e.toISOString().substring(0,19).replace("T"," "):(e.toLocaleString||e.toString).apply(e)}}]),n.filter("humanReadableFileSize",["$filter","fileManagerConfig",function(e,n){var t=[" kB"," MB"," GB"," TB","PB","EB","ZB","YB"],r=["KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"];return function(e){var i=-1,a=e;do{a/=1024,i++}while(a>1024);var o=n.useBinarySizePrefixes?r[i]:t[i];return Math.max(a,.1).toFixed(1)+" "+o}}])}(angular),function(e){"use strict";e.module("FileManagerApp").provider("fileManagerConfig",function(){var n={appName:"angular-filemanager v1.5",defaultLang:"en",listUrl:"bridges/php/handler.php",uploadUrl:"bridges/php/handler.php",renameUrl:"bridges/php/handler.php",copyUrl:"bridges/php/handler.php",moveUrl:"bridges/php/handler.php",removeUrl:"bridges/php/handler.php",editUrl:"bridges/php/handler.php",getContentUrl:"bridges/php/handler.php",createFolderUrl:"bridges/php/handler.php",downloadFileUrl:"bridges/php/handler.php",downloadMultipleUrl:"bridges/php/handler.php",compressUrl:"bridges/php/handler.php",extractUrl:"bridges/php/handler.php",permissionsUrl:"bridges/php/handler.php",searchForm:!0,sidebar:!0,breadcrumb:!0,allowedActions:{upload:!0,rename:!0,move:!0,copy:!0,edit:!0,changePermissions:!0,compress:!0,compressChooseName:!0,extract:!0,download:!0,downloadMultiple:!0,downloadLink:!0,preview:!0,remove:!0,createFolder:!0,pickFiles:!1,pickFolders:!1},multipleDownloadFileName:"angular-filemanager.zip",showExtensionIcons:!0,showSizeForDirectories:!1,useBinarySizePrefixes:!1,downloadFilesByAjax:!0,previewImagesInModal:!0,enablePermissionsRecursive:!0,compressAsync:!1,extractAsync:!1,pickCallback:null,isEditableFilePattern:/\.(txt|diff?|patch|svg|asc|cnf|cfg|conf|html?|.html|cfm|cgi|aspx?|ini|pl|py|md|css|cs|js|jsp|log|htaccess|htpasswd|gitignore|gitattributes|env|json|atom|eml|rss|markdown|sql|xml|xslt?|sh|rb|as|bat|cmd|cob|for|ftn|frm|frx|inc|lisp|scm|coffee|php[3-6]?|java|c|cbl|go|h|scala|vb|tmpl|lock|go|yml|yaml|tsv|lst)$/i,isImageFilePattern:/\.(jpe?g|gif|bmp|png|svg|tiff?)$/i,isExtractableFilePattern:/\.(gz|tar|rar|g?zip)$/i,tplPath:"src/templates"};return{$get:function(){return n},set:function(t){e.extend(n,t)}}})}(angular),function(e){"use strict";e.module("FileManagerApp").config(["$translateProvider",function(e){e.useSanitizeValueStrategy(null),e.translations("en",{filemanager:"File Manager",language:"Language",english:"English",spanish:"Spanish",portuguese:"Portuguese",french:"French",german:"German",hebrew:"Hebrew",slovak:"Slovak",chinese:"Chinese",russian:"Russian",ukrainian:"Ukrainian",turkish:"Turkish",persian:"Persian",confirm:"Confirm",cancel:"Cancel",close:"Close",upload_files:"Upload files",files_will_uploaded_to:"Files will be uploaded to",select_files:"Select files",uploading:"Uploading",permissions:"Permissions",select_destination_folder:"Select the destination folder",source:"Source",destination:"Destination",copy_file:"Copy file",sure_to_delete:"Are you sure to delete?",change_name_move:"Change name / move",enter_new_name_for:"Enter new name for",extract_item:"Extract item",extraction_started:"Extraction started in a background process",compression_started:"Compression started in a background process",enter_folder_name_for_extraction:"Enter the folder name for the extraction of",enter_file_name_for_compression:"Enter the file name for the compression of",toggle_fullscreen:"Toggle fullscreen",edit_file:"Edit file",file_content:"File content",loading:"Loading",search:"Search",create_folder:"Create folder",create:"Create",folder_name:"Folder name",upload:"Upload",change_permissions:"Change permissions",change:"Change",details:"Details",icons:"Icons",list:"List",name:"Name",size:"Size",actions:"Actions",date:"Date",no_files_in_folder:"No files in this folder",no_folders_in_folder:"This folder not contains children folders",select_this:"Select this",go_back:"Go back",wait:"Wait",move:"Move",download:"Download",copy_links:"Copy links",download_link:"Absolute download link",stream_link:"Relative stream link",file_path:"File path",view_item:"View item",remove:"Delete",edit:"Edit",copy:"Copy",rename:"Rename",extract:"Extract",compress:"Compress",error_invalid_filename:"Invalid filename or already exists, specify another name",error_modifying:"An error occurred modifying the file",error_deleting:"An error occurred deleting the file or folder",error_renaming:"An error occurred renaming the file",error_copying:"An error occurred copying the file",error_compressing:"An error occurred compressing the file or folder",error_extracting:"An error occurred extracting the file",error_creating_folder:"An error occurred creating the folder",error_getting_content:"An error occurred getting the content of the file",error_changing_perms:"An error occurred changing the permissions of the file",error_uploading_files:"An error occurred uploading files",sure_to_start_compression_with:"Are you sure to compress",owner:"Owner",group:"Group",others:"Others",read:"Read",write:"Write",delete:"Delete",exec:"Exec",original:"Original",changes:"Changes",recursive:"Recursive",preview:"Item preview",open:"Open",these_elements:"these {{total}} elements",new_folder:"New folder",download_as_zip:"Download as ZIP",roles:"Roles",domain:"Domain"}),e.translations("he",{filemanager:"מנהל קבצים",language:"שפה",english:"אנגלית",spanish:"ספרדית",portuguese:"פורטוגזית",french:"צרפתית",german:"גרמנית",hebrew:"עברי",slovak:"סלובקי",chinese:"סִינִית",russian:"רוּסִי",ukrainian:"אוקראיני",turkish:"טורקי",persian:"פַּרסִית",confirm:"אשר",cancel:"בטל",close:"סגור",upload_files:"העלה קבצים",files_will_uploaded_to:"הקבצים יעלו ל",select_files:"בחר קבצים",uploading:"מעלה",permissions:"הרשאות",select_destination_folder:"בחר תיקיית יעד",source:"מקור",destination:"יעד",copy_file:"העתק קובץ",sure_to_delete:"האם אתה בטוח שברצונך למחוק",change_name_move:"שנה שם / הזז",enter_new_name_for:"הקלד שם חדש עבור",extract_item:"חלץ פריט",extraction_started:"תהליך החילוץ מתבצע ברקע",compression_started:"תהליך הכיווץ מתבצע ברקע",enter_folder_name_for_extraction:"הקלד שם תיקייה לחילוץ עבור",enter_file_name_for_compression:"הזן את שם הקובץ עבור הדחיסה של",toggle_fullscreen:"הפעל/בטל מסך מלא",edit_file:"ערוך קובץ",file_content:"תוכן הקובץ",loading:"טוען",search:"חפש",create_folder:"צור תיקייה",create:"צור",folder_name:"שם תיקייה",upload:"העלה",change_permissions:"שנה הרשאות",change:"שנה",details:"פרטים",icons:"סמלים",list:"רשימה",name:"שם",size:"גודל",actions:"פעולות",date:"תאריך",no_files_in_folder:"אין קבצים בתיקייה זו",no_folders_in_folder:"התיקייה הזו אינה כוללת תתי תיקיות",select_this:"בחר את זה",go_back:"חזור אחורה",wait:"חכה",move:"הזז",download:"הורד",view_item:"הצג פריט",remove:"מחק",edit:"ערוך",copy:"העתק",rename:"שנה שם",extract:"חלץ",compress:"כווץ",error_invalid_filename:"שם קובץ אינו תקין או קיים, ציין שם קובץ אחר",error_modifying:"התרחשה שגיאה בעת שינוי הקובץ",error_deleting:"התרחשה שגיאה בעת מחיקת הקובץ או התיקייה",error_renaming:"התרחשה שגיאה בעת שינוי שם הקובץ",error_copying:"התרחשה שגיאה בעת העתקת הקובץ",error_compressing:"התרחשה שגיאה בעת כיווץ הקובץ או התיקייה",error_extracting:"התרחשה שגיאה בעת חילוץ הקובץ או התיקייה",error_creating_folder:"התרחשה שגיאה בעת יצירת התיקייה",error_getting_content:"התרחשה שגיאה בעת בקשת תוכן הקובץ",error_changing_perms:"התרחשה שגיאה בעת שינוי הרשאות הקובץ",error_uploading_files:"התרחשה שגיאה בעת העלאת הקבצים",sure_to_start_compression_with:"האם אתה בטוח שברצונך לכווץ",owner:"בעלים",group:"קבוצה",others:"אחרים",read:"קריאה",write:"כתיבה",exec:"הרצה",original:"מקורי",changes:"שינויים",recursive:"רקורסיה",preview:"הצגת פריט",open:"פתח",new_folder:"תיקיה חדשה",download_as_zip:"להוריד כמו"}),e.translations("pt",{filemanager:"Gerenciador de arquivos",language:"Língua",english:"Inglês",spanish:"Espanhol",portuguese:"Portugues",french:"Francês",german:"Alemão",hebrew:"Hebraico",slovak:"Eslovaco",chinese:"Chinês",russian:"Russo",ukrainian:"Ucraniano",turkish:"Turco",persian:"Persa",confirm:"Confirmar",cancel:"Cancelar",close:"Fechar",upload_files:"Carregar arquivos",files_will_uploaded_to:"Os arquivos serão enviados para",select_files:"Selecione os arquivos",uploading:"Carregar",permissions:"Autorizações",select_destination_folder:"Selecione a pasta de destino",source:"Origem",destination:"Destino",copy_file:"Copiar arquivo",sure_to_delete:"Tem certeza de que deseja apagar",change_name_move:"Renomear / mudança",enter_new_name_for:"Digite o novo nome para",extract_item:"Extrair arquivo",extraction_started:"A extração começou em um processo em segundo plano",compression_started:"A compressão começou em um processo em segundo plano",enter_folder_name_for_extraction:"Digite o nome da pasta para a extração de",enter_file_name_for_compression:"Digite o nome do arquivo para a compressão de",toggle_fullscreen:"Ativar/desativar tela cheia",edit_file:"Editar arquivo",file_content:"Conteúdo do arquivo",loading:"Carregando",search:"Localizar",create_folder:"Criar Pasta",create:"Criar",folder_name:"Nome da pasta",upload:"Fazer",change_permissions:"Alterar permissões",change:"Alterar",details:"Detalhes",icons:"Icones",list:"Lista",name:"Nome",size:"Tamanho",actions:"Ações",date:"Data",no_files_in_folder:"Não há arquivos nesta pasta",no_folders_in_folder:"Esta pasta não contém subpastas",select_this:"Selecione esta",go_back:"Voltar",wait:"Espere",move:"Mover",download:"Baixar",view_item:"Veja o arquivo",remove:"Excluir",edit:"Editar",copy:"Copiar",rename:"Renomear",extract:"Extrair",compress:"Comprimir",error_invalid_filename:"Nome do arquivo inválido ou nome de arquivo já existe, especifique outro nome",error_modifying:"Ocorreu um erro ao modificar o arquivo",error_deleting:"Ocorreu um erro ao excluir o arquivo ou pasta",error_renaming:"Ocorreu um erro ao mudar o nome do arquivo",error_copying:"Ocorreu um erro ao copiar o arquivo",error_compressing:"Ocorreu um erro ao comprimir o arquivo ou pasta",error_extracting:"Ocorreu um erro ao extrair o arquivo",error_creating_folder:"Ocorreu um erro ao criar a pasta",error_getting_content:"Ocorreu um erro ao obter o conteúdo do arquivo",error_changing_perms:"Ocorreu um erro ao alterar as permissões do arquivo",error_uploading_files:"Ocorreu um erro upload de arquivos",sure_to_start_compression_with:"Tem certeza que deseja comprimir",owner:"Proprietário",group:"Grupo",others:"Outros",read:"Leitura",write:"Escrita ",exec:"Execução",original:"Original",changes:"Mudanças",recursive:"Recursiva",preview:"Visualização",open:"Abrir",these_elements:"estes {{total}} elements",new_folder:"Nova pasta",download_as_zip:"Download como ZIP"}),e.translations("es",{filemanager:"Administrador de archivos",language:"Idioma",english:"Ingles",spanish:"Español",portuguese:"Portugues",french:"Francés",german:"Alemán",hebrew:"Hebreo",slovak:"Eslovaco",chinese:"Chino",russian:"Ruso",ukrainian:"Ucraniano",turkish:"Turco",persian:"Persa",confirm:"Confirmar",cancel:"Cancelar",close:"Cerrar",upload_files:"Subir archivos",files_will_uploaded_to:"Los archivos seran subidos a",select_files:"Seleccione los archivos",uploading:"Subiendo",permissions:"Permisos",select_destination_folder:"Seleccione la carpeta de destino",source:"Origen",destination:"Destino",copy_file:"Copiar archivo",sure_to_delete:"Esta seguro que desea eliminar",change_name_move:"Renombrar / mover",enter_new_name_for:"Ingrese el nuevo nombre para",extract_item:"Extraer archivo",extraction_started:"La extraccion ha comenzado en un proceso de segundo plano",compression_started:"La compresion ha comenzado en un proceso de segundo plano",enter_folder_name_for_extraction:"Ingrese el nombre de la carpeta para la extraccion de",enter_file_name_for_compression:"Ingrese el nombre del archivo para la compresion de",toggle_fullscreen:"Activar/Desactivar pantalla completa",edit_file:"Editar archivo",file_content:"Contenido del archivo",loading:"Cargando",search:"Buscar",create_folder:"Crear carpeta",create:"Crear",folder_name:"Nombre de la carpeta",upload:"Subir",change_permissions:"Cambiar permisos",change:"Cambiar",details:"Detalles",icons:"Iconos",list:"Lista",name:"Nombre",size:"Tamaño",actions:"Acciones",date:"Fecha",no_files_in_folder:"No hay archivos en esta carpeta",no_folders_in_folder:"Esta carpeta no contiene sub-carpetas",select_this:"Seleccionar esta",go_back:"Volver",wait:"Espere",move:"Mover",download:"Descargar",view_item:"Ver archivo",remove:"Eliminar",edit:"Editar",copy:"Copiar",rename:"Renombrar",extract:"Extraer",compress:"Comprimir",error_invalid_filename:"El nombre del archivo es invalido o ya existe",error_modifying:"Ocurrio un error al intentar modificar el archivo",error_deleting:"Ocurrio un error al intentar eliminar el archivo",error_renaming:"Ocurrio un error al intentar renombrar el archivo",error_copying:"Ocurrio un error al intentar copiar el archivo",error_compressing:"Ocurrio un error al intentar comprimir el archivo",error_extracting:"Ocurrio un error al intentar extraer el archivo",error_creating_folder:"Ocurrio un error al intentar crear la carpeta",error_getting_content:"Ocurrio un error al obtener el contenido del archivo",error_changing_perms:"Ocurrio un error al cambiar los permisos del archivo",error_uploading_files:"Ocurrio un error al subir archivos",sure_to_start_compression_with:"Esta seguro que desea comprimir",owner:"Propietario",group:"Grupo",others:"Otros",read:"Lectura",write:"Escritura",exec:"Ejecucion",original:"Original",changes:"Cambios",recursive:"Recursivo",preview:"Vista previa",open:"Abrir",these_elements:"estos {{total}} elementos",new_folder:"Nueva carpeta",download_as_zip:"Descargar como ZIP"}),e.translations("fr",{filemanager:"Gestionnaire de fichier",language:"Langue",english:"Anglais",spanish:"Espagnol",portuguese:"Portugais",french:"Français",german:"Allemand",hebrew:"Hébreu",slovak:"Slovaque",chinese:"Chinois",russian:"Russe",ukrainian:"Ukrainien",turkish:"Turc",persian:"Persan",confirm:"Confirmer",cancel:"Annuler",close:"Fermer",upload_files:"Télécharger des fichiers",files_will_uploaded_to:"Les fichiers seront uploadé dans",select_files:"Sélectionnez les fichiers",uploading:"Upload en cours",permissions:"Permissions",select_destination_folder:"Sélectionné le dossier de destination",source:"Source",destination:"Destination",copy_file:"Copier le fichier",sure_to_delete:"Êtes-vous sûr de vouloir supprimer",change_name_move:"Renommer / Déplacer",enter_new_name_for:"Entrer le nouveau nom pour",extract_item:"Extraires les éléments",extraction_started:"L'extraction a démarré en tâche de fond",compression_started:"La compression a démarré en tâche de fond",enter_folder_name_for_extraction:"Entrer le nom du dossier pour l'extraction de",enter_file_name_for_compression:"Entrez le nom de fichier pour la compression de",toggle_fullscreen:"Basculer en plein écran",edit_file:"Éditer le fichier",file_content:"Contenu du fichier",loading:"Chargement en cours",search:"Recherche",create_folder:"Créer un dossier",create:"Créer",folder_name:"Nom du dossier",upload:"Upload",change_permissions:"Changer les permissions",change:"Changer",details:"Details",icons:"Icons",list:"Liste",name:"Nom",size:"Taille",actions:"Actions",date:"Date",no_files_in_folder:"Aucun fichier dans ce dossier",no_folders_in_folder:"Ce dossier ne contiens pas de dossier",select_this:"Sélectionner",go_back:"Retour",wait:"Patienter",move:"Déplacer",download:"Télécharger",view_item:"Voir l'élément",remove:"Supprimer",edit:"Éditer",copy:"Copier",rename:"Renommer",extract:"Extraire",compress:"Compresser",error_invalid_filename:"Nom de fichier invalide ou déjà existant, merci de spécifier un autre nom",error_modifying:"Une erreur est survenue pendant la modification du fichier",error_deleting:"Une erreur est survenue pendant la suppression du fichier ou du dossier",error_renaming:"Une erreur est survenue pendant le renommage du fichier",error_copying:"Une erreur est survenue pendant la copie du fichier",error_compressing:"Une erreur est survenue pendant la compression du fichier ou du dossier",error_extracting:"Une erreur est survenue pendant l'extraction du fichier",error_creating_folder:"Une erreur est survenue pendant la création du dossier",error_getting_content:"Une erreur est survenue pendant la récupération du contenu du fichier",error_changing_perms:"Une erreur est survenue pendant le changement des permissions du fichier",error_uploading_files:"Une erreur est survenue pendant l'upload des fichiers",sure_to_start_compression_with:"Êtes-vous sûre de vouloir compresser",owner:"Propriétaire",group:"Groupe",others:"Autres",read:"Lecture",write:"Écriture",exec:"Éxécution",original:"Original",changes:"Modifications",recursive:"Récursif",preview:"Aperçu",open:"Ouvrir",these_elements:"ces {{total}} éléments",new_folder:"Nouveau dossier",download_as_zip:"Télécharger comme ZIP"}),e.translations("de",{filemanager:"Dateimanager",language:"Sprache",english:"Englisch",spanish:"Spansisch",portuguese:"Portugiesisch",french:"Französisch",german:"Deutsch",hebrew:"Hebräisch",slovak:"Slowakisch",chinese:"Chinesisch",russian:"Russisch",ukrainian:"Ukrainisch",turkish:"Türkisch",persian:"Persisch",confirm:"Bestätigen",cancel:"Abbrechen",close:"Schließen",upload_files:"Hochladen von Dateien",files_will_uploaded_to:"Dateien werden hochgeladen nach",select_files:"Wählen Sie die Dateien",uploading:"Lade hoch",permissions:"Berechtigungen",select_destination_folder:"Wählen Sie einen Zielordner",source:"Quelle",destination:"Ziel",copy_file:"Datei kopieren",sure_to_delete:"Sind Sie sicher, dass Sie die Datei löschen möchten?",change_name_move:"Namen ändern / verschieben",enter_new_name_for:"Geben Sie den neuen Namen ein für",extract_item:"Archiv entpacken",extraction_started:"Entpacken hat im Hintergrund begonnen",compression_started:"Komprimierung hat im Hintergrund begonnen",enter_folder_name_for_extraction:"Geben sie den verzeichnisnamen für die entpackung an, von",enter_file_name_for_compression:"Geben sie den dateinamen für die kompression von",toggle_fullscreen:"Vollbild umschalten",edit_file:"Datei bearbeiten",file_content:"Dateiinhalt",loading:"Lade",search:"Suche",create_folder:"Ordner erstellen",create:"Erstellen",folder_name:"Verzeichnisname",upload:"Hochladen",change_permissions:"Berechtigungen ändern",change:"Ändern",details:"Details",icons:"Symbolansicht",list:"Listenansicht",name:"Name",size:"Größe",actions:"Aktionen",date:"Datum",no_files_in_folder:"Keine Dateien in diesem Ordner",no_folders_in_folder:"Dieser Ordner enthält keine Unterordner",select_this:"Auswählen",go_back:"Zurück",wait:"Warte",move:"Verschieben",download:"Herunterladen",copy_links:"Links kopieren",download_link:"Absoluter Download Link",stream_link:"Relativer Stream Link",file_path:"Datei Pfad",view_item:"Datei ansehen",remove:"Löschen",edit:"Bearbeiten",copy:"Kopieren",rename:"Umbenennen",extract:"Entpacken",compress:"Komprimieren",error_invalid_filename:"Ungültiger Dateiname oder existiert bereits",error_modifying:"Beim Bearbeiten der Datei ist ein Fehler aufgetreten",error_deleting:"Beim Löschen der Datei oder des Ordners ist ein Fehler aufgetreten",error_renaming:"Beim Umbennenen der Datei ist ein Fehler aufgetreten",error_copying:"Beim Kopieren der Datei ist ein Fehler aufgetreten",error_compressing:"Beim Komprimieren der Datei oder des Ordners ist ein Fehler aufgetreten",error_extracting:"Beim Entpacken der Datei ist ein Fehler aufgetreten",error_creating_folder:"Beim Erstellen des Ordners ist ein Fehler aufgetreten",error_getting_content:"Beim Holen des Dateiinhalts ist ein Fehler aufgetreten",error_changing_perms:"Beim Ändern der Dateiberechtigungen ist ein Fehler aufgetreten",error_uploading_files:"Beim Hochladen der Dateien ist ein Fehler aufgetreten",sure_to_start_compression_with:"Möchten Sie die Datei wirklich komprimieren?",owner:"Besitzer",group:"Gruppe",others:"Andere",read:"Lesen",write:"Schreiben",delete:"Löschen",exec:"Ausführen",original:"Original",changes:"Änderungen",recursive:"Rekursiv",preview:"Dateivorschau",open:"Öffnen",these_elements:"diese {{total}} elemente",new_folder:"Neuer Ordner",download_as_zip:"Download als ZIP",roles:"Rollen",domain:"Domain"}),e.translations("sk",{filemanager:"Správca súborov",language:"Jazyk",english:"Angličtina",spanish:"Španielčina",portuguese:"Portugalčina",french:"Francúzština",german:"Nemčina",hebrew:"Hebrejčina",slovak:"Slovenčina",chinese:"Čínština",russian:"Ruský",ukrainian:"Ukrajinský",turkish:"Turecký",persian:"Perzský",confirm:"Potvrdiť",cancel:"Zrušiť",close:"Zavrieť",upload_files:"Nahrávať súbory",files_will_uploaded_to:"Súbory budú nahrané do",select_files:"Vybrať súbory",uploading:"Nahrávanie",permissions:"Oprávnenia",select_destination_folder:"Vyberte cieľový príečinok",source:"Zdroj",destination:"Cieľ",copy_file:"Kopírovať súbor",sure_to_delete:"Ste si istý, že chcete vymazať",change_name_move:"Premenovať / Premiestniť",enter_new_name_for:"Zadajte nové meno pre",extract_item:"Rozbaliť položku",extraction_started:"Rozbaľovanie začalo v procese na pozadí",compression_started:"Kompresia začala v procese na pzoadí",enter_folder_name_for_extraction:"Zadajte názov priečinka na rozbalenie",enter_file_name_for_compression:"Zadajte názov súboru pre kompresiu",toggle_fullscreen:"Prepnúť režim na celú obrazovku",edit_file:"Upraviť súbor",file_content:"Obsah súboru",loading:"Načítavanie",search:"Hľadať",create_folder:"Vytvoriť priečinok",create:"Vytvoriť",folder_name:"Názov priećinka",upload:"Nahrať",change_permissions:"Zmeniť oprávnenia",change:"Zmeniť",details:"Podrobnosti",icons:"Ikony",list:"Zoznam",name:"Meno",size:"Veľkosť",actions:"Akcie",date:"Dátum",no_files_in_folder:"V tom to priečinku nie sú žiadne súbory",no_folders_in_folder:"Tento priečinok neobsahuje žiadne ďalšie priećinky",select_this:"Vybrať tento",go_back:"Ísť späť",wait:"Počkajte",move:"Presunúť",download:"Stiahnuť",view_item:"Zobraziť položku",remove:"Vymazať",edit:"Upraviť",copy:"Kopírovať",rename:"Premenovať",extract:"Rozbaliť",compress:"Komprimovať",error_invalid_filename:"Neplatné alebo duplicitné meno súboru, vyberte iné meno",error_modifying:"Vyskytla sa chyba pri upravovaní súboru",error_deleting:"Vyskytla sa chyba pri mazaní súboru alebo priečinku",error_renaming:"Vyskytla sa chyba pri premenovaní súboru",error_copying:"Vyskytla sa chyba pri kopírovaní súboru",error_compressing:"Vyskytla sa chyba pri komprimovaní súboru alebo priečinka",error_extracting:"Vyskytla sa chyba pri rozbaľovaní súboru",error_creating_folder:"Vyskytla sa chyba pri vytváraní priečinku",error_getting_content:"Vyskytla sa chyba pri získavaní obsahu súboru",error_changing_perms:"Vyskytla sa chyba pri zmene oprávnení súboru",error_uploading_files:"Vyskytla sa chyba pri nahrávaní súborov",sure_to_start_compression_with:"Ste si istý, že chcete komprimovať",owner:"Vlastník",group:"Skupina",others:"Ostatní",read:"Čítanie",write:"Zapisovanie",exec:"Spúštanie",original:"Originál",changes:"Zmeny",recursive:"Rekurzívne",preview:"Náhľad položky",open:"Otvoriť",these_elements:"týchto {{total}} prvkov",new_folder:"Nový priečinok",download_as_zip:"Stiahnuť ako ZIP"}),e.translations("zh",{filemanager:"文档管理器",language:"语言",english:"英语",spanish:"西班牙语",portuguese:"葡萄牙语",french:"法语",german:"德语",hebrew:"希伯来语",slovak:"斯洛伐克语",chinese:"中文",russian:"俄語",ukrainian:"烏克蘭",turkish:"土耳其",persian:"波斯語",confirm:"确定",cancel:"取消",close:"关闭",upload_files:"上传文件",files_will_uploaded_to:"文件将上传到",select_files:"选择文件",uploading:"上传中",permissions:"权限",select_destination_folder:"选择目标文件",source:"源自",destination:"目的地",copy_file:"复制文件",sure_to_delete:"确定要删除?",change_name_move:"改名或移动?",enter_new_name_for:"输入新的名称",extract_item:"解压",extraction_started:"解压已经在后台开始",compression_started:"压缩已经在后台开始",enter_folder_name_for_extraction:"输入解压的目标文件夹",enter_file_name_for_compression:"输入要压缩的文件名",toggle_fullscreen:"切换全屏",edit_file:"编辑文件",file_content:"文件内容",loading:"加载中",search:"搜索",create_folder:"创建文件夹",create:"创建",folder_name:"文件夹名称",upload:"上传",change_permissions:"修改权限",change:"修改",details:"详细信息",icons:"图标",list:"列表",name:"名称",size:"尺寸",actions:"操作",date:"日期",no_files_in_folder:"此文件夹没有文件",no_folders_in_folder:"此文件夹不包含子文件夹",select_this:"选择此文件",go_back:"后退",wait:"等待",move:"移动",download:"下载",view_item:"查看子项",remove:"删除",edit:"编辑",copy:"复制",rename:"重命名",extract:"解压",compress:"压缩",error_invalid_filename:"非法文件名或文件已经存在, 请指定其它名称",error_modifying:"修改文件出错",error_deleting:"删除文件或文件夹出错",error_renaming:"重命名文件出错",error_copying:"复制文件出错",error_compressing:"压缩文件或文件夹出错",error_extracting:"解压文件出错",error_creating_folder:"创建文件夹出错",error_getting_content:"获取文件内容出错",error_changing_perms:"修改文件权限出错",error_uploading_files:"上传文件出错",sure_to_start_compression_with:"确定要压缩?",owner:"拥有者",group:"群组",others:"其他",read:"读取",write:"写入",exec:"执行",original:"原始",changes:"变化",recursive:"递归",preview:"成员预览",open:"打开",these_elements:"共 {{total}} 个",new_folder:"新文件夹",download_as_zip:"下载的ZIP"}),e.translations("ru",{filemanager:"Файловый менеджер",language:"Язык",english:"Английский",spanish:"Испанский",portuguese:"Португальский",french:"Французкий",german:"Немецкий",hebrew:"Хинди",slovak:"Словацкий",chinese:"Китайский",russian:"русский",ukrainian:"украинец",turkish:"турецкий",persian:"персидский",confirm:"Подьвердить",cancel:"Отменить",close:"Закрыть",upload_files:"Загрузка файлов",files_will_uploaded_to:"Файлы будут загружены в: ",select_files:"Выберите файлы",uploading:"Загрузка",permissions:"Разрешения",select_destination_folder:"Выберите папку назначения",source:"Источкик",destination:"Цель",copy_file:"Скопировать файл",sure_to_delete:"Действительно удалить?",change_name_move:"Переименовать / переместить",enter_new_name_for:"Новое имя для",extract_item:"Извлечь",extraction_started:"Извлечение начато",compression_started:"Сжатие начато",enter_folder_name_for_extraction:"Извлечь в укананную папку",enter_file_name_for_compression:"Введите имя архива",toggle_fullscreen:"На весь экран",edit_file:"Редактировать",file_content:"Содержимое файла",loading:"Загрузка",search:"Поиск",create_folder:"Создать папку",create:"Создать",folder_name:"Имя папки",upload:"Загрузить",change_permissions:"Изменить разрешения",change:"Изменить",details:"Свойства",icons:"Иконки",list:"Список",name:"Имя",size:"Размер",actions:"Действия",date:"Дата",no_files_in_folder:"Пустая папка",no_folders_in_folder:"Пустая папка",select_this:"Выбрать",go_back:"Назад",wait:"Подождите",move:"Переместить",download:"Скачать",view_item:"Отобразить содержимое",remove:"Удалить",edit:"Редактировать",copy:"Скопировать",rename:"Переименовать",extract:"Извлечь",compress:"Сжать",error_invalid_filename:"Имя неверное или уже существует, выберите другое",error_modifying:"Произошла ошибка при модифицировании файла",error_deleting:"Произошла ошибка при удалении",error_renaming:"Произошла ошибка при переименовании файла",error_copying:"Произошла ошибка при копировании файла",error_compressing:"Произошла ошибка при сжатии",error_extracting:"Произошла ошибка при извлечении",error_creating_folder:"Произошла ошибка при создании папки",error_getting_content:"Произошла ошибка при получении содержимого",error_changing_perms:"Произошла ошибка при изменении разрешений",error_uploading_files:"Произошла ошибка при загрузке",sure_to_start_compression_with:"Действительно сжать",owner:"Владелец",group:"Группа",others:"Другие",read:"Чтение",write:"Запись",exec:"Выполнение",original:"По-умолчанию",changes:"Изменения",recursive:"Рекурсивно",preview:"Просмотр",open:"Открыть",these_elements:"всего {{total}} елементов",new_folder:"Новая папка",download_as_zip:"Download as ZIP"}),e.translations("ua",{filemanager:"Файловий менеджер",language:"Мова",english:"Англійська",spanish:"Іспанська",portuguese:"Португальська",french:"Французька",german:"Німецька",hebrew:"Хінді",slovak:"Словацька",chinese:"Китайська",russian:"російський",ukrainian:"український",turkish:"турецька",persian:"перський",confirm:"Підтвердити",cancel:"Відмінити",close:"Закрити",upload_files:"Завантаження файлів",files_will_uploaded_to:"Файли будуть завантажені у: ",select_files:"Виберіть файли",uploading:"Завантаження",permissions:"Дозволи",select_destination_folder:"Виберіть папку призначення",source:"Джерело",destination:"Ціль",copy_file:"Скопіювати файл",sure_to_delete:"Дійсно удалить?",change_name_move:"Перейменувати / перемістити",enter_new_name_for:"Нове ім'я для",extract_item:"Извлечь",extraction_started:"Извлечение начато",compression_started:"Архівацію почато",enter_folder_name_for_extraction:"Извлечь в укананную папку",enter_file_name_for_compression:"Введите имя архива",toggle_fullscreen:"На весь экран",edit_file:"Редагувати",file_content:"Вміст файлу",loading:"Завантаження",search:"Пошук",create_folder:"Створити папку",create:"Створити",folder_name:"Ім'я папки",upload:"Завантижити",change_permissions:"Змінити дозволи",change:"Редагувати",details:"Властивості",icons:"Іконки",list:"Список",name:"Ім'я",size:"Розмір",actions:"Дії",date:"Дата",no_files_in_folder:"Пуста папка",no_folders_in_folder:"Пуста папка",select_this:"Выбрати",go_back:"Назад",wait:"Зачекайте",move:"Перемістити",download:"Скачати",view_item:"Показати вміст",remove:"Видалити",edit:"Редагувати",copy:"Копіювати",rename:"Переіменувати",extract:"Розархівувати",compress:"Архівувати",error_invalid_filename:"Ім'я певірне або вже існує, виберіть інше",error_modifying:"Виникла помилка при редагуванні файлу",error_deleting:"Виникла помилка при видаленні",error_renaming:"Виникла помилка при зміні імені файлу",error_copying:"Виникла помилка при коміюванні файлу",error_compressing:"Виникла помилка при стисненні",error_extracting:"Виникла помилка при розархівації",error_creating_folder:"Виникла помилка при створенні папки",error_getting_content:"Виникла помилка при отриманні вмісту",error_changing_perms:"Виникла помилка при зміні дозволів",error_uploading_files:"Виникла помилка при завантаженні",sure_to_start_compression_with:"Дійсно стиснути",owner:"Власник",group:"Група",others:"Інші",read:"Читання",write:"Запис",exec:"Виконання",original:"За замовчуванням",changes:"Зміни",recursive:"Рекурсивно",preview:"Перегляд",open:"Відкрити",these_elements:"усього {{total}} елементів",new_folder:"Нова папка",download_as_zip:"Download as ZIP"}),e.translations("tr",{filemanager:"Dosya Yöneticisi",language:"Dil",english:"İngilizce",spanish:"İspanyolca",portuguese:"Portekizce",french:"Fransızca",german:"Almanca",hebrew:"İbranice",slovak:"Slovakça",chinese:"Çince",russian:"Rusça",ukrainian:"Ukrayna",turkish:"Türk",persian:"Farsça",confirm:"Onayla",cancel:"İptal Et",close:"Kapat",upload_files:"Dosya yükle",files_will_uploaded_to:"Dosyalar yüklenecektir.",select_files:"Dosya Seç",uploading:"Yükleniyor",permissions:"İzinler",select_destination_folder:"Hedef klasör seçin",source:"Kaynak",destination:"Hedef",copy_file:"Dosyayı kopyala",sure_to_delete:"Silmek istediğinden emin misin",change_name_move:"İsmini değiştir / taşı",enter_new_name_for:"Yeni ad girin",extract_item:"Dosya çıkar",extraction_started:"Çıkarma işlemi arkaplanda devam ediyor",compression_started:"Sıkıştırma işlemi arkaplanda başladı",enter_folder_name_for_extraction:"Çıkarılması için klasör adı girin",enter_file_name_for_compression:"Sıkıştırılması için dosya adı girin",toggle_fullscreen:"Tam ekran moduna geç",edit_file:"Dosyayı düzenle",file_content:"Dosya içeriği",loading:"Yükleniyor",search:"Ara",create_folder:"Klasör oluştur",create:"Oluştur",folder_name:"Klasör adı",upload:"Yükle",change_permissions:"İzinleri değiştir",change:"Değiştir",details:"Detaylar",icons:"simgeler",list:"Liste",name:"Adı",size:"Boyutu",actions:"İşlemler",date:"Tarih",no_files_in_folder:"Klasörde hiç dosya yok",no_folders_in_folder:"Bu klasör alt klasör içermez",select_this:"Bunu seç",go_back:"Geri git",wait:"Bekle",move:"Taşı",download:"İndir",view_item:"Dosyayı görüntüle",remove:"Sil",edit:"Düzenle",copy:"Kopyala",rename:"Yeniden Adlandır",extract:"Çıkart",compress:"Sıkıştır",error_invalid_filename:"Geçersiz dosya adı, bu dosya adına sahip dosya mevcut",error_modifying:"Dosya düzenlenirken bir hata oluştu",error_deleting:"Klasör veya dosya silinirken bir hata oluştu",error_renaming:"Dosya yeniden adlandırılırken bir hata oluştu",error_copying:"Dosya kopyalanırken bir hata oluştu",error_compressing:"Dosya veya klasör sıkıştırılırken bir hata oluştu",error_extracting:"Çıkartılırken bir hata oluştu",error_creating_folder:"Klasör oluşturulurken bir hata oluştu",error_getting_content:"Dosya detayları alınırken bir hata oluştu",error_changing_perms:"Dosyanın izini değiştirilirken bir hata oluştu",error_uploading_files:"Dosyalar yüklenirken bir hata oluştu",sure_to_start_compression_with:"Sıkıştırmak istediğinden emin misin",owner:"Sahip",group:"Grup",others:"Diğerleri",read:"Okuma",write:"Yazma",exec:"Gerçekleştir",original:"Orjinal",changes:"Değişiklikler",recursive:"Yinemeli",preview:"Dosyayı önizle",open:"Aç",these_elements:"{{total}} eleman",new_folder:"Yeni Klasör",download_as_zip:"ZIP olarak indir"}),e.translations("fa",{filemanager:"مدیریت فایل ها",language:"زبان",english:"انگلیسی",spanish:"اسپانیایی",portuguese:"پرتغالی",french:"فرانسه",german:"آلمانی",hebrew:"عبری",slovak:"اسلواک",chinese:"چینی",russian:"روسی",ukrainian:"اوکراینی",turkish:"ترکی",persian:"فارسی",confirm:"تایید",cancel:"رد",close:"بستن",upload_files:"آپلود فایل",files_will_uploaded_to:"فایل ها آپلود می شوند به",select_files:"انتخاب فایل ها",uploading:"در حال آپلود",permissions:"مجوز ها",select_destination_folder:"پوشه مقصد را انتخاب کنید",source:"مبدا",destination:"مقصد",copy_file:"کپی فایل",sure_to_delete:"مطمين هستید می خواهید حذف کنید؟",change_name_move:"تغییر نام و جابجایی",enter_new_name_for:"نام جدیدی وارد کنید برای",extract_item:"خارج کردن از حالت فشرده",extraction_started:"یک پروسه در پس زمینه شروع به خارج کردن از حالت فشرده کرد",compression_started:"یک پروسه در پس زمینه شروع به فشرده سازی کرد",enter_folder_name_for_extraction:"نام پوشه مقصد برای خارج کردن از حالت فشرده را وارد کنید",enter_file_name_for_compression:"نام پوشه مقصد برای فشرده سازی را وارد کنید",toggle_fullscreen:"تعویض حالت تمام صفحه",edit_file:"ویرایش",file_content:"محتویات",loading:"در حال بارگذاری",search:"جستجو",create_folder:"پوشه جدید",create:"ساختن",folder_name:"نام پوشه",upload:"آپلود",change_permissions:"تغییر مجوز ها",change:"تغییر",details:"جزییات",icons:"آیکون ها",list:"لیست",name:"نام",size:"سایز",actions:"اعمال",date:"تاریخ",no_files_in_folder:"هیچ فایلی در این پوشه نیست",no_folders_in_folder:"هیچ پوشه ای داخل این پوشه قرار ندارد",select_this:"انتخاب",go_back:"بازگشت",wait:"منتظر بمانید",move:"جابجایی",download:"دانلود",view_item:"مشاهده این مورد",remove:"حذف",edit:"ویرایش",copy:"کپی",rename:"تغییر نام",extract:"خروج از حالت فشرده",compress:"فشرده سازی",error_invalid_filename:"نام فایل مورد درست نیست و یا قبلا استفاده شده است، لطفا نام دیگری وارد کنید",error_modifying:"در هنگام تغییر فایل خطایی پیش آمد",error_deleting:"در هنگام حذف فایل خطایی پیش آمد",error_renaming:"در هنگام تغییر نام فایل خطایی پیش آمد",error_copying:"در هنگام کپی کردن فایل خطایی پیش آمد",error_compressing:"در هنگام فشرده سازی فایل خطایی پیش آمد",error_extracting:"در هنگام خارک کردن فایل از حالت فشرده خطایی پیش آمد",error_creating_folder:"در هنگام ساخت پوشه خطایی پیش امد",error_getting_content:"در هنگام بارگذاری محتویات فایل خطایی رخ داد",error_changing_perms:"در هنگام تغییر مجوز های فایل خطایی رخ داد",error_uploading_files:"در آپلود فایل خطایی رخ داد",sure_to_start_compression_with:"مطمئن هستید فشرده سازی انجام شد؟",owner:"مالک فایل",group:"گروه",others:"دیگران",read:"خواندن",write:"نوشتن",exec:"اجرا کردن",original:"اصلی",changes:"تغییرات",recursive:"بازگشتی",preview:"پیش نمایش",open:"باز کردن",these_elements:"تعداد {{total}} مورد",new_folder:"پوشه جدید",download_as_zip:"به عنوان فایل فشرده دانلود شود"})}])}(angular),function(e,n){"use strict";e.module("FileManagerApp").service("apiHandler",["$http","$q","$window","$translate","Upload",function(e,t,r,i,a){e.defaults.headers.common["X-Requested-With"]="XMLHttpRequest";var o=function(){this.inprocess=!1,this.asyncSuccess=!1,this.error=""};return o.prototype.deferredHandler=function(e,n,t,r){return e&&"object"==typeof e||(this.error="Error %s - Bridge response error, please check the API docs or this ajax response.".replace("%s",t)),404==t&&(this.error="Error 404 - Backend bridge is not working, please check the ajax response."),e.result&&e.result.error&&(this.error=e.result.error),!this.error&&e.error&&(this.error=e.error.message),!this.error&&r&&(this.error=r),this.error?n.reject(e):n.resolve(e)},o.prototype.list=function(n,r,i,a){var o=this,l=i||o.deferredHandler,s=t.defer(),d={action:"list",path:r,recycle:a};return o.inprocess=!0,o.error="",e.post(n,d).success(function(e,n){l(e,s,n)}).error(function(e,n){l(e,s,n,"Unknown error listing, check the response")})["finally"](function(){o.inprocess=!1}),s.promise},o.prototype.copy=function(n,r,a,o){var l=this,s=t.defer(),d={action:"copy",items:r,newPath:a};return o&&1===r.length&&(d.singleFilename=o),l.inprocess=!0,l.error="",e.post(n,d).success(function(e,n){l.deferredHandler(e,s,n)}).error(function(e,n){l.deferredHandler(e,s,n,i.instant("error_copying"))})["finally"](function(){l.inprocess=!1}),s.promise},o.prototype.move=function(n,r,a){var o=this,l=t.defer(),s={action:"move",items:r,newPath:a};return o.inprocess=!0,o.error="",e.post(n,s).success(function(e,n){o.deferredHandler(e,l,n)}).error(function(e,n){o.deferredHandler(e,l,n,i.instant("error_moving"))})["finally"](function(){o.inprocess=!1}),l.promise},o.prototype.remove=function(n,r){var a=this,o=t.defer(),l={action:"remove",items:r};return a.inprocess=!0,a.error="",e.post(n,l).success(function(e,n){a.deferredHandler(e,o,n)}).error(function(e,n){a.deferredHandler(e,o,n,i.instant("error_deleting"))})["finally"](function(){a.inprocess=!1}),o.promise},o.prototype.upload=function(e,n,r){var i=this,o=t.defer();i.inprocess=!0,i.progress=0,i.error="";for(var l={destination:n},s=0;sr;r++)t+=n.charAt(Math.floor(Math.random()*n.length));return t}t.backUp=[],t.varButtonLabel="",t.spacingProperty="",t.indexProperty="",t.orientationH=!1,t.orientationV=!0,t.filteredModel=[],t.inputLabel={labelFilter:""},t.tabIndex=0,t.lang={},t.helperStatus={all:!0,none:!0,reset:!0,filter:!0};var o=0,l=[],s=0,d="",c=[],p=0,u=null;t.clearClicked=function(e){t.inputLabel.labelFilter="",t.updateFilter(),t.select("clear",e)},t.numberToArray=function(e){return new Array(e)},t.searchChanged=function(){return t.inputLabel.labelFilter.length0?!1:void t.updateFilter()},t.updateFilter=function(){t.filteredModel=[];var e=0;if("undefined"==typeof t.inputModel)return!1;for(e=t.inputModel.length-1;e>=0;e--){"undefined"!=typeof t.inputModel[e][i.groupProperty]&&t.inputModel[e][i.groupProperty]===!1&&t.filteredModel.push(t.inputModel[e]);var r=!1;if("undefined"==typeof t.inputModel[e][i.groupProperty]){if("undefined"!=typeof i.searchProperty&&""!==i.searchProperty){for(var a in t.inputModel[e])if("boolean"!=typeof t.inputModel[e][a]&&String(t.inputModel[e][a]).toUpperCase().indexOf(t.inputLabel.labelFilter.toUpperCase())>=0&&i.searchProperty.indexOf(a)>-1){r=!0;break}}else for(var a in t.inputModel[e])if("boolean"!=typeof t.inputModel[e][a]&&String(t.inputModel[e][a]).toUpperCase().indexOf(t.inputLabel.labelFilter.toUpperCase())>=0){r=!0;break}r===!0&&t.filteredModel.push(t.inputModel[e])}"undefined"!=typeof t.inputModel[e][i.groupProperty]&&t.inputModel[e][i.groupProperty]===!0&&("undefined"!=typeof t.filteredModel[t.filteredModel.length-1][i.groupProperty]&&t.filteredModel[t.filteredModel.length-1][i.groupProperty]===!1?t.filteredModel.pop():t.filteredModel.push(t.inputModel[e]))}t.filteredModel.reverse(),n(function(){if(t.getFormElements(),t.inputLabel.labelFilter.length>p){var e=[];angular.forEach(t.filteredModel,function(n,r){if("undefined"!=typeof n&&"undefined"==typeof n[i.groupProperty]){var a=angular.copy(n),o=e.push(a);delete e[o-1][t.indexProperty],delete e[o-1][t.spacingProperty]}}),t.onSearchChange({data:{keyword:t.inputLabel.labelFilter,result:e}})}},0)},t.getFormElements=function(){c=[];var e=[],n=[],i=[],a=[];t.helperStatus.all||t.helperStatus.none||t.helperStatus.reset?(e=r.children().children().next().children().children()[0].getElementsByTagName("button"),t.helperStatus.filter&&(n=r.children().children().next().children().children().next()[0].getElementsByTagName("input"),a=r.children().children().next().children().children().next()[0].getElementsByTagName("button"))):t.helperStatus.filter&&(n=r.children().children().next().children().children()[0].getElementsByTagName("input"),a=r.children().children().next().children().children()[0].getElementsByTagName("button")),i=t.helperStatus.all||t.helperStatus.none||t.helperStatus.reset||t.helperStatus.filter?r.children().children().next().children().next()[0].getElementsByTagName("input"):r.children().children().next()[0].getElementsByTagName("input");for(var o=0;ol);d++)if("undefined"!=typeof t.filteredModel[d][i.groupProperty]&&t.filteredModel[d][i.groupProperty]===!0)0===f.length&&(p=d+1),g+=1;else if("undefined"!=typeof t.filteredModel[d][i.groupProperty]&&t.filteredModel[d][i.groupProperty]===!1){if(g-=1,f.length>0&&0===g){var h=!0;for(m=d,c=0;c=c;c++)"undefined"==typeof t.filteredModel[c][i.groupProperty]&&("undefined"==typeof i.disableProperty?(t.filteredModel[c][t.tickProperty]=!1,v=t.filteredModel[c][t.indexProperty],t.inputModel[v][t.tickProperty]=!1):t.filteredModel[c][i.disableProperty]!==!0&&(t.filteredModel[c][t.tickProperty]=!1,v=t.filteredModel[c][t.indexProperty],t.inputModel[v][t.tickProperty]=!1));else for(c=p;m>=c;c++)"undefined"==typeof t.filteredModel[c][i.groupProperty]&&("undefined"==typeof i.disableProperty?(t.filteredModel[c][t.tickProperty]=!0,v=t.filteredModel[c][t.indexProperty],t.inputModel[v][t.tickProperty]=!0):t.filteredModel[c][i.disableProperty]!==!0&&(t.filteredModel[c][t.tickProperty]=!0,v=t.filteredModel[c][t.indexProperty],t.inputModel[v][t.tickProperty]=!0))}}else f.push(t.filteredModel[d])}else{if("undefined"!=typeof i.selectionMode&&"SINGLE"===i.selectionMode.toUpperCase()){for(d=0;d-1&&(n[r]=t)});var o=t.outputModel.push(n);delete t.outputModel[o-1][t.indexProperty],delete t.outputModel[o-1][t.spacingProperty]}})):angular.forEach(t.inputModel,function(e,n){if("undefined"!=typeof e&&"undefined"==typeof e[i.groupProperty]&&e[t.tickProperty]===!0){var r=angular.copy(e),a=t.outputModel.push(r);delete t.outputModel[a-1][t.indexProperty],delete t.outputModel[a-1][t.spacingProperty]}})},t.refreshButton=function(){t.varButtonLabel="";var n=0;if(0===t.outputModel.length)t.varButtonLabel=t.lang.nothingSelected;else{var r=t.outputModel.length;"undefined"!=typeof i.maxLabels&&""!==i.maxLabels&&(r=i.maxLabels),t.outputModel.length>r?t.more=!0:t.more=!1,angular.forEach(t.inputModel,function(e,a){"undefined"!=typeof e&&e[i.tickProperty]===!0&&(r>n&&(t.varButtonLabel+=(t.varButtonLabel.length>0?',
':'
')+t.writeLabel(e,"buttonLabel")),n++)}),t.more===!0&&(r>0&&(t.varButtonLabel+=", ... "),t.varButtonLabel+="("+t.outputModel.length+")")}t.varButtonLabel=e.trustAsHtml(t.varButtonLabel+'')},t.itemIsDisabled=function(e){return"undefined"!=typeof i.disableProperty&&e[i.disableProperty]===!0?!0:t.isDisabled===!0},t.writeLabel=function(n,t){var r=i[t].split(" "),a="";return angular.forEach(r,function(e,t){n[e]&&(a+=" "+e.split(".").reduce(function(e,n){return e[n]},n))}),"BUTTONLABEL"===t.toUpperCase()?a:e.trustAsHtml(a)},t.toggleCheckboxes=function(e){var i=r.children()[0];if(angular.element(document).off("click",t.externalClickListener),angular.element(document).off("keydown",t.keyboardListener),angular.element(d).hasClass("show"))angular.element(d).removeClass("show"),angular.element(i).removeClass("buttonClicked"),angular.element(document).off("click",t.externalClickListener),angular.element(document).off("keydown",t.keyboardListener),t.removeFocusStyle(t.tabIndex),"undefined"!=typeof c[t.tabIndex]&&c[t.tabIndex].blur(),n(function(){t.onClose()},0),r.children().children()[0].focus();else{t.inputLabel.labelFilter="",t.updateFilter(),l=[],s=0,angular.element(d).addClass("show"),angular.element(i).addClass("buttonClicked"),angular.element(document).on("click",t.externalClickListener),angular.element(document).on("keydown",t.keyboardListener),t.getFormElements(),t.tabIndex=0;var a=angular.element(r[0].querySelector(".helperContainer"))[0];if("undefined"!=typeof a){for(var o=0;o0&&(c[t.tabIndex].focus(),t.setFocusStyle(t.tabIndex),angular.element(r).children()[0].blur())),t.onOpen()}},t.externalClickListener=function(e){for(var i=r.find(e.target.tagName),a=0;ac.length-1&&(t.tabIndex=0,o=c.length-1);c[t.tabIndex].disabled===!0&&(t.tabIndex++,t.tabIndex>c.length-1&&(t.tabIndex=0),t.tabIndex!==o););else if(38===n||37===n||e.shiftKey&&9==n)for(r=!0,o=t.tabIndex,t.tabIndex--,t.tabIndex<0&&(t.tabIndex=c.length-1,o=0);c[t.tabIndex].disabled===!0&&(t.tabIndex--,t.tabIndex!==o);)t.tabIndex<0&&(t.tabIndex=c.length-1);if(r===!0){e.preventDefault(),c[t.tabIndex].focus();var i=document.activeElement;"CHECKBOX"===i.type.toUpperCase()?(t.setFocusStyle(t.tabIndex),t.removeFocusStyle(o)):(t.removeFocusStyle(o),t.removeFocusStyle(s),t.removeFocusStyle(c.length-1))}r=!1},t.setFocusStyle=function(e){angular.element(c[e]).parent().parent().parent().addClass("multiSelectFocus")},t.removeFocusStyle=function(e){angular.element(c[e]).parent().parent().parent().removeClass("multiSelectFocus")},t.groupProperty=i.groupProperty,t.tickProperty=i.tickProperty,t.directiveId=i.directiveId;var m=a(5);if(t.indexProperty="idx_"+m,t.spacingProperty="spc_"+m,"undefined"!=typeof i.orientation&&("HORIZONTAL"===i.orientation.toUpperCase()?(t.orientationH=!0,t.orientationV=!1):(t.orientationH=!1,t.orientationV=!0)),d=r.children().children().next()[0],"undefined"!=typeof i.maxHeight){var f=r.children().children().children()[0];angular.element(f).attr("style","height:"+i.maxHeight+"; overflow-y:scroll;")}for(var g in t.helperStatus)t.helperStatus.hasOwnProperty(g)&&"undefined"!=typeof i.helperElements&&-1===i.helperElements.toUpperCase().indexOf(g.toUpperCase())&&(t.helperStatus[g]=!1);"undefined"!=typeof i.selectionMode&&"SINGLE"===i.selectionMode.toUpperCase()&&(t.helperStatus.all=!1,t.helperStatus.none=!1),t.icon={},t.icon.selectAll="✓",t.icon.selectNone="×",t.icon.reset="↶",t.icon.tickMark="✓","undefined"!=typeof i.translation?(t.lang.selectAll=e.trustAsHtml(t.icon.selectAll+"  "+t.translation.selectAll),t.lang.selectNone=e.trustAsHtml(t.icon.selectNone+"  "+t.translation.selectNone),t.lang.reset=e.trustAsHtml(t.icon.reset+"  "+t.translation.reset),t.lang.search=t.translation.search,t.lang.nothingSelected=e.trustAsHtml(t.translation.nothingSelected)):(t.lang.selectAll=e.trustAsHtml(t.icon.selectAll+"  Select All"),t.lang.selectNone=e.trustAsHtml(t.icon.selectNone+"  Select None"),t.lang.reset=e.trustAsHtml(t.icon.reset+"  Reset"),t.lang.search="Search...",t.lang.nothingSelected="None Selected"),t.icon.tickMark=e.trustAsHtml(t.icon.tickMark),"undefined"!=typeof i.MinSearchLength&&parseInt(i.MinSearchLength)>0&&(p=Math.floor(parseInt(i.MinSearchLength))),t.$watch("inputModel",function(e){e&&(t.refreshOutputModel(),t.refreshButton())},!0),t.$watch("inputModel",function(e){e&&(t.backUp=angular.copy(t.inputModel),t.updateFilter(),t.prepareGrouping(),t.prepareIndex(),t.refreshOutputModel(),t.refreshButton())}),t.$watch("isDisabled",function(e){t.isDisabled=e});var h=function(e){t.$apply(function(){t.scrolled=!1})};angular.element(document).bind("touchstart",h);var v=function(e){t.$apply(function(){t.scrolled=!0})};angular.element(document).bind("touchmove",v),t.$on("$destroy",function(){angular.element(document).unbind("touchstart",h),angular.element(document).unbind("touchmove",v)})}}}]).run(["$templateCache",function(e){var n='
';e.put("isteven-multi-select.htm",n)}]),angular.module("FileManagerApp").run(["$templateCache",function(e){e.put("src/templates/current-folder-breadcrumb.html",''),e.put("src/templates/item-context-menu.html",''),e.put("src/templates/main-icons.html",'
\n \n\n
\n
\n
\n\n
\n {{"no_files_in_folder" | translate}}...\n
\n \n
\n {{ fileNavigator.error }}\n
\n
'),e.put("src/templates/main-table-modal.html",'\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{"name" | translate}}\n \n \n
\n
\n
\n {{"no_folders_in_folder" | translate}}...\n \n \n
\n {{ fileNavigator.error }}\n
\n \n \n {{item.model.name | strLimit : 32}}\n \n \n \n
'),e.put("src/templates/main-table.html",'\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{"name" | translate}}\n \n \n
\n
\n
\n {{"no_files_in_folder" | translate}}...\n
\n {{ fileNavigator.error }}\n
\n \n \n \n {{item.model.name | strLimit : 64}}\n \n
\n'),e.put("src/templates/main.html",'
\n
\n\n
\n
\n\n \n\n
\n \n
\n
\n
\n\n
\n
\n
\n'),e.put("src/templates/modals.html",'\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n
\n
\n\n\n\n\n\n\n\n\n\n\n\n"); +$templateCache.put("src/templates/navbar.html",""); +$templateCache.put("src/templates/sidebar.html","
    \n
  • \n
\n\n"); +$templateCache.put("src/templates/spinner.html","
\n \n \n \n
");}]); \ No newline at end of file From 6abff081cb5d32a72f7c02c0cde9bcf7f2fd0823 Mon Sep 17 00:00:00 2001 From: amk Date: Mon, 7 Sep 2020 11:11:38 +0200 Subject: [PATCH 4/4] updated filemanager.js --- src/assets/dist/angular-filemanager.min.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/dist/angular-filemanager.min.js b/src/assets/dist/angular-filemanager.min.js index 6b100e2..d9c2f7f 100755 --- a/src/assets/dist/angular-filemanager.min.js +++ b/src/assets/dist/angular-filemanager.min.js @@ -26,7 +26,7 @@ } menu.hide().css( { - position: 'fixed', + position: 'absolute', left: leftBorder, top: e.pageY-offset.top }).show(); @@ -3821,6 +3821,6 @@ $templateCache.put("src/templates/main-table-modal.html","\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n {{\"name\" | translate}}\n \n \n \n \n {{\"size\" | translate}}\n \n \n \n \n {{\"date\" | translate}}\n \n \n \n \n {{\"permissions\" | translate}}\n \n \n
\n
\n
\n {{\"no_files_in_folder\" | translate}}...\n
\n {{ fileNavigator.error }}\n
\n \n \n \n {{item.model.name | strLimit : 64}}\n \n \n \n {{item.model.size | humanReadableFileSize}}\n \n \n {{item.model.date | formatDate }}\n \n {{item.model.perms.toCode(item.model.type === \'dir\'?\'d\':\'-\')}}\n
\n"); $templateCache.put("src/templates/main.html","
\n
\n\n
\n
\n\n
\n
\n\n
\n
\n
\n
\n
\n\n
\n
\n
\n"); $templateCache.put("src/templates/modals.html","
\n
\n
\n
\n \n

{{\"preview\" | translate}}

\n
\n
\n
\n\n \"{{singleSelection().model.name}}\"\n {{\'loading\' | translate}} ...\n
\n
\n
\n
\n \n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\"confirm\" | translate}}

\n
\n
\n {{\'sure_to_delete\' | translate}} \n\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'move\' | translate}}

\n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n\n
\n
\n
\n
\n
\n \n

{{\'rename\' | translate}}

\n
\n
\n \n \n\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'copy_file\' | translate}}

\n
\n
\n
\n \n \n
\n\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'compress\' | translate}}

\n
\n
\n
\n
{{\'compression_started\' | translate}}
\n
\n
\n
\n {{\'sure_to_start_compression_with\' | translate}} {{singleSelection().model.name}} ?\n
\n
\n \n \n
\n
\n\n
\n
\n
\n
\n \n
\n
\n \n \n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'extract_item\' | translate}}

\n
\n
\n
\n
{{\'extraction_started\' | translate}}
\n
\n
\n \n \n
\n
\n
\n
\n
\n \n
\n
\n \n \n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n \n

{{\'edit_file\' | translate}}

\n
\n
\n \n {{\'loading\' | translate}} ...\n \n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\'new_folder\' | translate}}

\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n
\n \n

{{\"upload_files\" | translate}}

\n
\n
\n \n \n\n
\n
    \n
  • \n \n
    {{uploadFile.name}}
    \n

    {{uploadFile.size | humanReadableFileSize}}

    \n
  • \n
\n
\n {{\"uploading\" | translate}}... {{apiMiddleware.apiHandler.progress}}%\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n \n
\n \n

{{\'change_permissions\' | translate}}

\n
\n
\n
\n
\n

{{\'read\' | translate}}

\n \n
\n
\n
\n
\n
\n
\n

{{\'write\' | translate}}

\n\n \n
\n
\n
\n
\n
\n
\n

{{\'delete\' | translate}}

\n \n
\n
\n
\n
\n
\n
\n
\n \n \n
\n \n \n \n\n\n
\n
\n
\n
\n
\n \n

{{\'copy_links\' | translate}}

\n
\n
\n\n \n\n
\n \n \n \n \n
\n\n \n\n
\n \n \n \n \n
\n\n \n\n
\n \n \n \n \n
\n\n
\n
\n \n
\n
\n
\n
\n
\n\n
\n
\n
\n
\n \n

{{\"select_destination_folder\" | translate}}

\n
\n
\n
\n
\n
\n
\n \n
\n
\n
\n \n
\n
\n
\n
\n\n\n\n\n\n\n"); -$templateCache.put("src/templates/navbar.html",""); +$templateCache.put("src/templates/navbar.html",""); $templateCache.put("src/templates/sidebar.html","
    \n
  • \n
\n\n"); $templateCache.put("src/templates/spinner.html","
\n \n \n \n
");}]); \ No newline at end of file