Wallet/src/js/directives/directives.js

306 lines
8.8 KiB
JavaScript
Raw Normal View History

2014-03-14 17:38:27 -03:00
'use strict';
function selectText(element) {
2015-03-06 12:00:10 -03:00
var doc = document;
if (doc.body.createTextRange) { // ms
var range = doc.body.createTextRange();
range.moveToElementText(element);
range.select();
} else if (window.getSelection) {
var selection = window.getSelection();
var range = doc.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
2015-03-06 12:00:10 -03:00
}
}
angular.module('copayApp.directives')
2015-03-06 12:00:10 -03:00
.directive('validAddress', ['$rootScope', 'bitcore', 'profileService',
function($rootScope, bitcore, profileService) {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
var URI = bitcore.URI;
var Address = bitcore.Address
var validator = function(value) {
2015-04-24 10:28:25 -03:00
if (!profileService.focusedClient)
return;
2015-04-24 02:42:10 -03:00
var networkName = profileService.focusedClient.credentials.network;
2015-03-06 12:00:10 -03:00
// Regular url
if (/^https?:\/\//.test(value)) {
ctrl.$setValidity('validAddress', true);
return value;
}
2015-03-06 12:00:10 -03:00
// Bip21 uri
if (/^bitcoin:/.test(value)) {
var uri, isAddressValid;
var isUriValid = URI.isValid(value);
if (isUriValid) {
uri = new URI(value);
isAddressValid = Address.isValid(uri.address.toString(), networkName)
}
ctrl.$setValidity('validAddress', isUriValid && isAddressValid);
return value;
}
2015-03-06 12:00:10 -03:00
if (typeof value == 'undefined') {
ctrl.$pristine = true;
return;
}
2014-09-12 10:24:27 -03:00
2015-03-06 12:00:10 -03:00
// Regular Address
ctrl.$setValidity('validAddress', Address.isValid(value, networkName));
2014-08-13 18:07:57 -04:00
return value;
2015-03-06 12:00:10 -03:00
};
2014-08-13 18:07:57 -04:00
2014-09-12 10:24:27 -03:00
2015-03-06 12:00:10 -03:00
ctrl.$parsers.unshift(validator);
ctrl.$formatters.unshift(validator);
}
};
}
])
.directive('validUrl', [
function() {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
var validator = function(value) {
// Regular url
if (/^https?:\/\//.test(value)) {
ctrl.$setValidity('validUrl', true);
return value;
} else {
ctrl.$setValidity('validUrl', false);
return value;
}
};
ctrl.$parsers.unshift(validator);
ctrl.$formatters.unshift(validator);
}
};
}
])
2015-03-06 12:00:10 -03:00
.directive('validAmount', ['configService', '$locale',
function(configService, locale) {
2014-09-05 15:54:44 -07:00
2014-05-07 19:04:36 -03:00
return {
require: 'ngModel',
link: function(scope, element, attrs, ctrl) {
var val = function(value) {
2015-08-07 11:23:32 -03:00
if (value) value = value.replace(/,/g, '.');
2015-03-06 12:00:10 -03:00
var settings = configService.getSync().wallet.settings;
var vNum = Number((value * settings.unitToSatoshi).toFixed(0));
2014-08-15 23:00:12 -03:00
2015-08-07 11:23:32 -03:00
if (typeof value == 'undefined' || value == 0) {
2014-10-07 12:39:16 -03:00
ctrl.$pristine = true;
}
2014-05-07 19:04:36 -03:00
if (typeof vNum == "number" && vNum > 0) {
2015-03-06 12:00:10 -03:00
var decimals = Number(settings.unitDecimals);
2015-08-07 11:23:32 -03:00
var sep_index = ('' + value).indexOf('.');
var str_value = ('' + value).substring(sep_index + 1);
2014-10-07 12:39:16 -03:00
if (sep_index > 0 && str_value.length > decimals) {
ctrl.$setValidity('validAmount', false);
2014-05-07 19:04:36 -03:00
} else {
2014-10-07 12:39:16 -03:00
ctrl.$setValidity('validAmount', true);
2014-05-07 19:04:36 -03:00
}
} else {
2014-10-07 12:39:16 -03:00
ctrl.$setValidity('validAmount', false);
}
2014-05-07 19:04:36 -03:00
return value;
}
2014-05-07 19:04:36 -03:00
ctrl.$parsers.unshift(val);
ctrl.$formatters.unshift(val);
}
2014-05-07 19:04:36 -03:00
};
}
])
2015-03-06 12:00:10 -03:00
.directive('walletSecret', function(bitcore) {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
var validator = function(value) {
2015-03-06 12:00:10 -03:00
if (value.length > 0) {
2015-04-16 12:12:12 -03:00
var m = value.match(/^[0-9A-HJ-NP-Za-km-z]{70,80}$/);
2015-03-06 12:00:10 -03:00
ctrl.$setValidity('walletSecret', m ? true : false);
}
return value;
};
2014-05-14 14:24:24 -07:00
ctrl.$parsers.unshift(validator);
}
};
})
2014-05-07 19:04:36 -03:00
.directive('loading', function() {
2014-04-24 22:43:19 -03:00
return {
restrict: 'A',
link: function($scope, element, attr) {
2014-04-24 22:43:19 -03:00
var a = element.html();
var text = attr.loading;
element.on('click', function() {
element.html('<i class="size-21 fi-bitcoin-circle icon-rotate spinner"></i> ' + text + '...');
});
$scope.$watch('loading', function(val) {
if (!val) {
2014-04-24 22:43:19 -03:00
element.html(a);
}
});
}
}
})
2014-05-07 19:04:36 -03:00
.directive('ngFileSelect', function() {
return {
link: function($scope, el) {
el.bind('change', function(e) {
$scope.file = (e.srcElement || e.target).files[0];
$scope.getFile();
});
}
}
2014-05-26 15:03:39 -03:00
})
.directive('contact', function() {
return {
restrict: 'E',
link: function(scope, element, attrs) {
if (!scope.wallet) return;
var address = attrs.address;
var contact = scope.wallet.addressBook[address];
if (contact && !contact.hidden) {
element.append(contact.label);
2015-03-06 12:00:10 -03:00
element.attr('tooltip', attrs.address);
} else {
element.append(address);
}
element.bind('click', function() {
2014-11-20 03:10:43 -03:00
selectText(element[0]);
});
}
};
})
.directive('highlightOnChange', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(attrs.highlightOnChange, function(newValue, oldValue) {
element.addClass('highlight');
setTimeout(function() {
element.removeClass('highlight');
}, 500);
});
}
}
})
2014-05-26 15:03:39 -03:00
.directive('checkStrength', function() {
return {
replace: false,
restrict: 'EACM',
2014-06-02 14:39:12 -03:00
require: 'ngModel',
2014-05-26 15:03:39 -03:00
link: function(scope, element, attrs) {
var MIN_LENGTH = 8;
var MESSAGES = ['Very Weak', 'Very Weak', 'Weak', 'Medium', 'Strong', 'Very Strong'];
2014-12-18 20:05:13 -03:00
var COLOR = ['#dd514c', '#dd514c', '#faa732', '#faa732', '#16A085', '#16A085'];
function evaluateMeter(password) {
var passwordStrength = 0;
var text;
if (password.length > 0) passwordStrength = 1;
if (password.length >= MIN_LENGTH) {
if ((password.match(/[a-z]/)) && (password.match(/[A-Z]/))) {
passwordStrength++;
} else {
text = ', add mixed case';
}
if (password.match(/\d+/)) {
passwordStrength++;
} else {
if (!text) text = ', add numerals';
}
if (password.match(/.[!,@,#,$,%,^,&,*,?,_,~,-,(,)]/)) {
passwordStrength++;
} else {
if (!text) text = ', add punctuation';
}
if (password.length > 12) {
passwordStrength++;
} else {
if (!text) text = ', add characters';
}
} else {
text = ', that\'s short';
}
if (!text) text = '';
return {
strength: passwordStrength,
message: MESSAGES[passwordStrength] + text,
color: COLOR[passwordStrength]
2014-05-26 15:03:39 -03:00
}
}
2014-06-02 14:39:12 -03:00
scope.$watch(attrs.ngModel, function(newValue, oldValue) {
2014-05-26 15:03:39 -03:00
if (newValue && newValue !== '') {
var info = evaluateMeter(newValue);
2014-12-17 10:37:11 -03:00
scope[attrs.checkStrength] = info;
2014-05-26 15:03:39 -03:00
}
});
}
};
2014-06-16 15:51:19 -03:00
})
.directive('showFocus', function($timeout) {
return function(scope, element, attrs) {
2015-03-06 12:00:10 -03:00
scope.$watch(attrs.showFocus,
function(newValue) {
$timeout(function() {
2015-03-06 12:00:10 -03:00
newValue && element[0].focus();
});
2015-03-06 12:00:10 -03:00
}, true);
};
})
2014-08-13 18:07:57 -04:00
.directive('match', function() {
return {
require: 'ngModel',
restrict: 'A',
scope: {
2014-08-13 18:07:57 -04:00
match: '='
},
link: function(scope, elem, attrs, ctrl) {
scope.$watch(function() {
return (ctrl.$pristine && angular.isUndefined(ctrl.$modelValue)) || scope.match === ctrl.$modelValue;
}, function(currentValue) {
ctrl.$setValidity('match', currentValue);
});
}
};
})
.directive('clipCopy', function() {
return {
2014-12-16 10:47:31 +01:00
restrict: 'A',
2014-08-13 18:07:57 -04:00
scope: {
clipCopy: '=clipCopy'
},
link: function(scope, elm) {
// TODO this does not work (FIXME)
2015-03-06 12:00:10 -03:00
elm.attr('tooltip', 'Press Ctrl+C to Copy');
elm.attr('tooltip-placement', 'top');
elm.bind('click', function() {
selectText(elm[0]);
});
}
};
})
.directive('menuToggle', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'views/includes/menu-toggle.html'
}
});