| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- (function () {
- 'use strict';
- angular.module('ariaNg').directive('ngSetting', ['$timeout', '$q', 'ariaNgConstants', 'ariaNgLocalizationService', 'ariaNgKeyboardService', 'aria2SettingService', function ($timeout, $q, ariaNgConstants, ariaNgLocalizationService, ariaNgKeyboardService, aria2SettingService) {
- return {
- restrict: 'E',
- templateUrl: 'views/setting.html',
- require: '?ngModel',
- replace: true,
- scope: {
- option: '=',
- ngModel: '=',
- defaultValue: '=?',
- fixedValue: '=?',
- supportForceDeleteEmpty: '=?',
- onChangeValue: '&'
- },
- link: function (scope, element, attrs, ngModel) {
- var pendingSaveRequest = null;
- var options = {
- showPlaceholderCount: false,
- lazySaveTimeout: ariaNgConstants.lazySaveTimeout,
- errorTooltipPlacement: 'top',
- errorTooltipDelay: ariaNgConstants.errorTooltipDelay
- };
- angular.extend(options, attrs);
- var loadHistory = function () {
- if (!scope.option || !scope.option.showHistory) {
- return;
- }
- scope.history = aria2SettingService.getSettingHistory(scope.option.key);
- };
- var destroyTooltip = function () {
- angular.element(element).tooltip('destroy');
- };
- var showTooltip = function (cause, type, causeParams) {
- if (!cause) {
- return;
- }
- $timeout(function () {
- var currentValue = scope.optionStatus.getValue();
- if (currentValue !== 'failed' && currentValue !== 'error') {
- return;
- }
- angular.element(element).tooltip({
- animation: false,
- title: ariaNgLocalizationService.getLocalizedText(cause, causeParams),
- trigger: 'focus',
- placement: 'auto ' + options.errorTooltipPlacement,
- container: element,
- template:
- '<div class="tooltip' + (type ? ' tooltip-' + type : '') + '" role="tooltip">' +
- '<div class="tooltip-arrow"></div>' +
- '<div class="tooltip-inner"></div>' +
- '</div>'
- }).tooltip('show');
- }, options.errorTooltipDelay);
- };
- var getHumanReadableSize = function (size) {
- if (!size || parseInt(size).toString() != size) {
- return size;
- }
- var sizeUnits = ['', 'K', 'M', 'G'];
- var unitIndex = 0;
- for (var i = 0; i < sizeUnits.length; i++) {
- if ((size < 1024) || (size % 1024 !== 0)) {
- break;
- }
- size = size / 1024;
- unitIndex++;
- }
- return size + sizeUnits[unitIndex];
- };
- var getTotalCount = function (itemsText, separator, trim) {
- if (!itemsText || !separator || !angular.isString(itemsText)) {
- return 0;
- }
- var items = itemsText.split(separator);
- var totalCount = items.length;
- if (trim) {
- for (var i = 0; i < items.length; i++) {
- if (!items[i] || items[i] === '' || items[i].trim() === '') {
- totalCount--;
- }
- }
- }
- return totalCount;
- };
- var getHumanReadableValue = function (value) {
- if (scope.option.suffix === 'Bytes') {
- return getHumanReadableSize(value);
- }
- return value;
- };
- scope.optionStatus = (function () {
- var value = 'ready';
- return {
- getValue: function () {
- return value;
- },
- setReady: function () {
- destroyTooltip();
- value = 'ready';
- },
- setPending: function () {
- destroyTooltip();
- value = 'pending';
- },
- setSaving: function () {
- destroyTooltip();
- value = 'pending';
- },
- setSuccess: function () {
- destroyTooltip();
- value = 'success';
- },
- setFailed: function (cause) {
- destroyTooltip();
- value = 'failed';
- showTooltip(cause, 'warning');
- },
- setError: function (cause, causeParams) {
- destroyTooltip();
- value = 'error';
- showTooltip(cause, 'error', causeParams);
- },
- getStatusFeedbackStyle: function () {
- if (value === 'success') {
- return 'has-success';
- } else if (value === 'failed') {
- return 'has-warning';
- } else if (value === 'error') {
- return 'has-error';
- } else {
- return '';
- }
- },
- getStatusIcon: function () {
- if (value === 'pending') {
- return 'fa-hourglass-start';
- } else if (value === 'saving') {
- return 'fa-spin fa-pulse fa-spinner';
- } else if (value === 'success') {
- return 'fa-check';
- } else if (value === 'failed') {
- return 'fa-exclamation';
- } else if (value === 'error') {
- return 'fa-times';
- } else {
- return '';
- }
- },
- isShowStatusIcon: function () {
- return this.getStatusIcon() !== '';
- }
- };
- })();
- scope.getTotalCount = function () {
- var fixedValueCount = getTotalCount(scope.fixedValue, scope.option.separator, scope.option.trimCount);
- var inputValueCount = getTotalCount(scope.optionValue, scope.option.separator, scope.option.trimCount);
- if (!scope.optionValue && scope.showPlaceholderCount && scope.placeholderItemCount) {
- inputValueCount = scope.placeholderItemCount;
- }
- return fixedValueCount + inputValueCount;
- };
- scope.changeValue = function (optionValue, lazySave) {
- if (pendingSaveRequest) {
- $timeout.cancel(pendingSaveRequest);
- }
- scope.optionValue = optionValue;
- scope.optionStatus.setReady();
- if (!scope.option || !scope.option.key || scope.option.readonly) {
- return;
- }
- if (scope.option.required && optionValue === '') {
- scope.optionStatus.setError('Option value cannot be empty!');
- return;
- }
- if (optionValue !== '' && scope.option.type === 'integer' && !/^-?\d+$/.test(optionValue)) {
- scope.optionStatus.setError('Input number is invalid!');
- return;
- }
- if (optionValue !== '' && scope.option.type === 'float' && !/^-?(\d*\.)?\d+$/.test(optionValue)) {
- scope.optionStatus.setError('Input number is invalid!');
- return;
- }
- if (optionValue !== '' && (scope.option.type === 'integer' || scope.option.type === 'float') && (angular.isDefined(scope.option.min) || angular.isDefined(scope.option.max))) {
- var number = optionValue;
- if (scope.option.type === 'integer') {
- number = parseInt(optionValue);
- } else if (scope.option.type === 'float') {
- number = parseFloat(optionValue);
- }
- if (angular.isDefined(scope.option.min) && number < scope.option.min) {
- scope.optionStatus.setError('Input number is below min value!', { value: scope.option.min });
- return;
- }
- if (angular.isDefined(scope.option.max) && number > scope.option.max) {
- scope.optionStatus.setError('Input number is above max value!', { value: scope.option.max });
- return;
- }
- }
- if (optionValue !== '' && angular.isDefined(scope.option.pattern) && !(new RegExp(scope.option.pattern).test(optionValue))) {
- scope.optionStatus.setError('Input value is invalid!');
- return;
- }
- var data = {
- key: scope.option.key,
- value: optionValue,
- optionStatus: scope.optionStatus
- };
- var invokeChange = function () {
- scope.optionStatus.setSaving();
- scope.onChangeValue(data);
- };
- if (scope.onChangeValue) {
- if (lazySave) {
- scope.optionStatus.setPending();
- pendingSaveRequest = $timeout(function () {
- invokeChange();
- }, options.lazySaveTimeout);
- } else {
- invokeChange();
- }
- }
- };
- scope.inputKeyUp = function (event, lazySave) {
- if (options.deleteKeyAlwaysChangeValue === true || options.deleteKeyAlwaysChangeValue === 'true') {
- if (ariaNgKeyboardService.isBackspacePressed(event) || ariaNgKeyboardService.isDeletePressed(event)) {
- if (scope.optionValue && scope.optionValue !== '') {
- return; // onChange event has been triggered
- }
- scope.changeValue('', lazySave);
- }
- }
- };
- scope.filterHistory = function (userInput) {
- var result = [];
- if (scope.history && userInput) {
- for (var i = 0; i < scope.history.length; i++) {
- if (scope.history[i].indexOf(userInput) === 0) {
- result.push(scope.history[i]);
- }
- }
- }
- return $q.resolve(result);
- };
- if (ngModel) {
- scope.$watch(function () {
- return ngModel.$viewValue;
- }, function (value) {
- scope.optionValue = getHumanReadableValue(value);
- });
- }
- scope.$watch('option', function () {
- loadHistory();
- element.find('[data-toggle="popover"]').popover();
- });
- scope.$watch('defaultValue', function (value) {
- var displayValue = value;
- if (scope.option && scope.option.options) {
- for (var i = 0; i < scope.option.options.length; i++) {
- var optionItem = scope.option.options[i];
- if (optionItem.value === value) {
- displayValue = optionItem.name;
- break;
- }
- }
- }
- scope.placeholder = getHumanReadableValue(displayValue);
- if (scope.option) {
- scope.placeholderItemCount = getTotalCount(scope.placeholder, scope.option.separator, scope.option.trimCount);
- } else {
- scope.placeholderItemCount = 0;
- }
- });
- scope.showPlaceholderCount = options.showPlaceholderCount === true || options.showPlaceholderCount === 'true';
- loadHistory();
- }
- };
- }]);
- }());
|