diff --git a/bower.json b/bower.json index 75472cd..e03541b 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "angular-payments", - "version": "0.1.1", + "version": "0.1.2", "homepage": "https://github.com/laurihy/angular-payments", "authors": [ "Lauri Hynynen <@laurihy>" diff --git a/lib/angular-payments.js b/lib/angular-payments.js index bb1939a..01ba13b 100755 --- a/lib/angular-payments.js +++ b/lib/angular-payments.js @@ -9,7 +9,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') ret['parseExpiry'] = function(value){ var month, prefix, year, _ref; - value = value || '' + value = value || ''; value = value.replace(/\s/g, ''); _ref = value.split('/', 2), month = _ref[0], year = _ref[1]; @@ -27,7 +27,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') month: month, year: year }; - } + }; return ret; @@ -38,7 +38,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') var defaultFormat = /(\d{1,4})/g; var defaultInputFormat = /(?:^|\s)(\d{4})$/; - var cards = [ + var cards = [ { type: 'maestro', pattern: /^(5018|5020|5038|6304|6759|676[1-3])/, @@ -129,7 +129,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') } } - } + }; var _fromType = function(type) { var card, i, len; @@ -157,7 +157,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') .factory('_Format',['Cards', 'Common', '$filter', function(Cards, Common, $filter){ - var _formats = {} + var _formats = {}; var _hasTextSelected = function($target) { var ref; @@ -323,12 +323,15 @@ angular.module('angularPayments', []);angular.module('angularPayments') ctrl.$parsers.push(_parseCardNumber); ctrl.$formatters.push(_getFormattedCardNumber); - } + }; // cvc - _formatCVC = function(e){ + var _formatCVC = function(e){ + + var $target, digit, val; + $target = angular.element(e.currentTarget); digit = String.fromCharCode(e.which); @@ -345,15 +348,15 @@ angular.module('angularPayments', []);angular.module('angularPayments') e.preventDefault(); return; } - } + }; _formats['cvc'] = function(elem){ elem.bind('keypress', _formatCVC) - } + }; // expiry - _restrictExpiry = function(e) { + var _restrictExpiry = function(e) { var $target, digit, value; $target = angular.element(e.currentTarget); @@ -377,7 +380,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') } }; - _formatExpiry = function(e) { + var _formatExpiry = function(e) { var $target, digit, val; digit = String.fromCharCode(e.which); @@ -401,7 +404,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') } }; - _formatForwardExpiry = function(e) { + var _formatForwardExpiry = function(e) { var $target, digit, val; digit = String.fromCharCode(e.which); @@ -418,7 +421,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') } }; - _formatForwardSlash = function(e) { + var _formatForwardSlash = function(e) { var $target, slash, val; slash = String.fromCharCode(e.which); @@ -435,7 +438,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') } }; - _formatBackExpiry = function(e) { + var _formatBackExpiry = function(e) { var $target, value; if (e.meta) { @@ -492,7 +495,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') ctrl.$parsers.push(_parseExpiry); ctrl.$formatters.push(_getFormattedExpiry); - } + }; return function(type, elem, ctrl){ if(!_formats[type]){ @@ -523,7 +526,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') .factory('_Validate', ['Cards', 'Common', '$parse', function(Cards, Common, $parse){ - var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; } + var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; var _luhnCheck = function(num) { var digit, digits, odd, sum, i, len; @@ -575,7 +578,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') } else { return cvc.length >= 3 && cvc.length <= 4; } - } + }; _validators['card'] = function(num, ctrl, scope, attr){ var card, ref, typeModel; @@ -617,51 +620,45 @@ angular.module('angularPayments', []);angular.module('angularPayments') typeModel.assign(scope, card.type); } - ret = (ref = num.length, __indexOf.call(card.length, ref) >= 0) && (card.luhn === false || _luhnCheck(num)); - - return ret; - } + return (ref = num.length, __indexOf.call(card.length, ref) >= 0) && (card.luhn === false || _luhnCheck(num)); + }; _validators['expiry'] = function(val){ + var obj, currentTime, expiry, prefix; // valid if empty - let ng-required handle empty if(val == null || val.length == 0) return true; obj = Common.parseExpiry(val); - month = obj.month; - year = obj.year; - - var currentTime, expiry, prefix; - - if (!(month && year)) { + if (!(obj.month && obj.year)) { return false; } - if (!/^\d+$/.test(month)) { + if (!/^\d+$/.test(obj.month)) { return false; } - if (!/^\d+$/.test(year)) { + if (!/^\d+$/.test(obj.year)) { return false; } - if (!(parseInt(month, 10) <= 12)) { + if (!(parseInt(obj.month, 10) <= 12)) { return false; } - if (year.length === 2) { + if (obj.year.length === 2) { prefix = (new Date).getFullYear(); prefix = prefix.toString().slice(0, 2); - year = prefix + year; + obj.year = prefix + obj.year; } - expiry = new Date(year, month); + expiry = new Date(obj.year, obj.month); currentTime = new Date; expiry.setMonth(expiry.getMonth() - 1); expiry.setMonth(expiry.getMonth() + 1, 1); return expiry > currentTime; - } + }; return function(type, val, ctrl, scope, attr){ if(!_validators[type]){ @@ -680,7 +677,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') .factory('_ValidateWatch', ['_Validate', function(_Validate){ - var _validatorWatches = {} + var _validatorWatches = {}; _validatorWatches['cvc'] = function(type, ctrl, scope, attr){ if(attr.paymentsTypeModel) { @@ -691,7 +688,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') } }); } - } + }; return function(type, ctrl, scope, attr){ if(_validatorWatches[type]){ @@ -733,23 +730,23 @@ angular.module('angularPayments', []);angular.module('angularPayments') // filter valid stripe-values from scope and convert them from camelCase to snake_case - _getDataToSend = function(data){ + var _getDataToSend = function(data){ var possibleKeys = ['number', 'expMonth', 'expYear', 'cvc', 'name','addressLine1', 'addressLine2', 'addressCity', 'addressState', 'addressZip', - 'addressCountry'] + 'addressCountry']; var camelToSnake = function(str){ return str.replace(/([A-Z])/g, function(m){ return "_"+m.toLowerCase(); }); - } + }; var ret = {}; - for(i in possibleKeys){ + for(var i in possibleKeys){ if(data.hasOwnProperty(possibleKeys[i])){ ret[camelToSnake(possibleKeys[i])] = angular.copy(data[possibleKeys[i]]); } @@ -758,7 +755,7 @@ angular.module('angularPayments', []);angular.module('angularPayments') ret['number'] = (ret['number'] || '').replace(/ /g,''); return ret; - } + }; return { restrict: 'A', @@ -772,13 +769,13 @@ angular.module('angularPayments', []);angular.module('angularPayments') form.bind('submit', function() { - expMonthUsed = scope.expMonth ? true : false; - expYearUsed = scope.expYear ? true : false; + var expMonthUsed = scope.expMonth ? true : false; + var expYearUsed = scope.expYear ? true : false; if(!(expMonthUsed && expYearUsed)){ - exp = Common.parseExpiry(scope.expiry) - scope.expMonth = exp.month - scope.expYear = exp.year + var exp = Common.parseExpiry(scope.expiry); + scope.expMonth = exp.month; + scope.expYear = exp.year; } var button = form.find('button'); diff --git a/lib/angular-payments.min.js b/lib/angular-payments.min.js index 7fc3ada..ec4a4f8 100644 --- a/lib/angular-payments.min.js +++ b/lib/angular-payments.min.js @@ -1,2 +1,2 @@ -/*! angular-payments 11-09-2014 */ -angular.module("angularPayments",[]),angular.module("angularPayments").factory("Common",[function(){var a={};return a.parseExpiry=function(a){var b,c,d,e;return a=a||"",a=a.replace(/\s/g,""),e=a.split("/",2),b=e[0],d=e[1],2===(null!=d?d.length:void 0)&&/^\d+$/.test(d)&&(c=(new Date).getFullYear(),c=c.toString().slice(0,2),d=c+d),b=parseInt(b,10),d=parseInt(d,10),{month:b,year:d}},a}]),angular.module("angularPayments").factory("Cards",[function(){var a=/(\d{1,4})/g,b=/(?:^|\s)(\d{4})$/,c=[{type:"maestro",pattern:/^(5018|5020|5038|6304|6759|676[1-3])/,format:a,inputFormat:b,length:[12,13,14,15,16,17,18,19],cvcLength:[3],luhn:!0},{type:"dinersclub",pattern:/^(36|38|30[0-5])/,format:a,inputFormat:b,length:[14],cvcLength:[3],luhn:!0},{type:"laser",pattern:/^(6706|6771|6709)/,format:a,inputFormat:b,length:[16,17,18,19],cvcLength:[3],luhn:!0},{type:"jcb",pattern:/^35/,format:a,inputFormat:b,length:[16],cvcLength:[3],luhn:!0},{type:"unionpay",pattern:/^62/,format:a,inputFormat:b,length:[16,17,18,19],cvcLength:[3],luhn:!1},{type:"discover",pattern:/^(6011|65|64[4-9]|622)/,format:a,inputFormat:b,length:[16],cvcLength:[3],luhn:!0},{type:"mastercard",pattern:/^5[1-5]/,format:a,inputFormat:b,length:[16],cvcLength:[3],luhn:!0},{type:"amex",pattern:/^3[47]/,format:/(\d{1,4})(\d{1,6})?(\d{1,5})?/,inputFormat:/^(\d{4}|\d{4}\s\d{6})$/,length:[15],cvcLength:[3,4],luhn:!0},{type:"visa",pattern:/^4/,format:a,inputFormat:b,length:[13,14,15,16],cvcLength:[3],luhn:!0}],d=function(a){var b,d,e;for(a=(a+"").replace(/\D/g,""),d=0,e=c.length;e>d;d++)if(b=c[d],b.pattern.test(a))return b},e=function(a){var b,d,e;for(d=0,e=c.length;e>d;d++)if(b=c[d],b.type===a)return b};return{fromNumber:function(a){return d(a)},fromType:function(a){return e(a)},defaultFormat:function(){return a},defaultInputFormat:function(){return b}}}]),angular.module("angularPayments").factory("_Format",["Cards","Common","$filter",function(a,b,c){var d={},e=function(a){var b;return null!=a.prop("selectionStart")&&a.prop("selectionStart")!==a.prop("selectionEnd")?!0:("undefined"!=typeof document&&null!==document&&null!=(b=document.selection)&&"function"==typeof b.createRange?b.createRange().text:void 0)?!0:!1},f=function(b){var c,d,e,f,g,h,i;if(e=String.fromCharCode(b.which),c=angular.element(b.currentTarget),i=c.val(),d=a.fromNumber(i+e),f=(i.replace(/\D/g,"")+e).length,h=16,d&&(h=d.length[d.length.length-1]),!(f>=h)){if(!/^\d+$/.test(e)&&!b.meta&&b.keyCode>=46)return void b.preventDefault();if(null==c.prop("selectionStart")||c.prop("selectionStart")===i.length)return g=a.defaultInputFormat(),d&&(g=d.inputFormat),g.test(i)?(b.preventDefault(),c.val(i+" "+e)):g.test(i+e)?(b.preventDefault(),c.val(i+e+" ")):void 0}},g=function(b){var c,d,f,g;c=angular.element(b.currentTarget),f=String.fromCharCode(b.which),/^\d+$/.test(f)&&(e(c)||(g=(c.val()+f).replace(/\D/g,""),d=a.fromNumber(g),d?g.length<=d.length[d.length.length-1]||b.preventDefault():g.length<=16||b.preventDefault()))},h=function(a){var b,c;return b=angular.element(a.currentTarget),c=b.val(),a.meta||8!==a.which||null!=b.prop("selectionStart")&&b.prop("selectionStart")!==c.length?void 0:/\d\s$/.test(c)&&!a.meta&&a.keyCode>=46?(a.preventDefault(),b.val(c.replace(/\d\s$/,""))):/\s\d?$/.test(c)?(a.preventDefault(),b.val(c.replace(/\s\d?$/,""))):void 0},i=function(b){var c,d,e,f;return(c=a.fromNumber(b))?(e=c.length[c.length.length-1],b=b.replace(/\D/g,""),b=b.slice(0,+e+1||9e9),c.format.global?null!=(f=b.match(c.format))?f.join(" "):void 0:(d=c.format.exec(b),null!=d&&d.shift(),null!=d?d.join(" "):void 0)):b},j=function(a){return setTimeout(function(){var b,c;return b=angular.element(a.target),c=b.val(),c=i(c),b.val(c)})},k=function(a){return null!=a?a.replace(/\s/g,""):a};d.card=function(a,b){a.bind("keypress",g),a.bind("keypress",f),a.bind("keydown",h),a.bind("paste",j),b.$parsers.push(k),b.$formatters.push(i)},_formatCVC=function(a){return $target=angular.element(a.currentTarget),digit=String.fromCharCode(a.which),!/^\d+$/.test(digit)&&!a.meta&&a.keyCode>=46?void a.preventDefault():(val=$target.val()+digit,val.length<=4?void 0:void a.preventDefault())},d.cvc=function(a){a.bind("keypress",_formatCVC)},_restrictExpiry=function(a){var b,c,d;return b=angular.element(a.currentTarget),c=String.fromCharCode(a.which),!/^\d+$/.test(c)&&!a.meta&&a.keyCode>=46?void a.preventDefault():e(b)?void 0:(d=b.val()+c,d=d.replace(/\D/g,""),d.length>6?void a.preventDefault():void 0)},_formatExpiry=function(a){var b,c,d;return c=String.fromCharCode(a.which),!/^\d+$/.test(c)&&!a.meta&&a.keyCode>=46?void a.preventDefault():(b=angular.element(a.currentTarget),d=b.val()+c,/^\d$/.test(d)&&"0"!==d&&"1"!==d?(a.preventDefault(),b.val("0"+d+" / ")):/^\d\d$/.test(d)?(a.preventDefault(),b.val(""+d+" / ")):void 0)},_formatForwardExpiry=function(a){var b,c,d;return c=String.fromCharCode(a.which),!/^\d+$/.test(c)&&!a.meta&&a.keyCode>=46?void 0:(b=angular.element(a.currentTarget),d=b.val(),/^\d\d$/.test(d)?b.val(""+d+" / "):void 0)},_formatForwardSlash=function(a){var b,c,d;return c=String.fromCharCode(a.which),"/"===c?(b=angular.element(a.currentTarget),d=b.val(),/^\d$/.test(d)&&"0"!==d?b.val("0"+d+" / "):void 0):void 0},_formatBackExpiry=function(a){var b,c;if(!a.meta&&(b=angular.element(a.currentTarget),c=b.val(),8===a.which&&(null==b.prop("selectionStart")||b.prop("selectionStart")===c.length)))return/\d(\s|\/)+$/.test(c)?(a.preventDefault(),b.val(c.replace(/\d(\s|\/)*$/,""))):/\s\/\s?\d?$/.test(c)?(a.preventDefault(),b.val(c.replace(/\s\/\s?\d?$/,""))):void 0};var l=function(a){if(null!=a){var d=b.parseExpiry(a),e=new Date(d.year,d.month-1);return c("date")(e,"MM/yyyy")}return null},m=function(a){if(null!=a){var d=b.parseExpiry(a),e=new Date(d.year,d.month-1);return c("date")(e,"MM / yyyy")}return null};return d.expiry=function(a,b){a.bind("keypress",_restrictExpiry),a.bind("keypress",_formatExpiry),a.bind("keypress",_formatForwardSlash),a.bind("keypress",_formatForwardExpiry),a.bind("keydown",_formatBackExpiry),b.$parsers.push(l),b.$formatters.push(m)},function(a,b,c){if(!d[a])throw types=Object.keys(d),errstr='Unknown type for formatting: "'+a+'". ',errstr+='Should be one of: "'+types.join('", "')+'"';return d[a](b,c)}}]).directive("paymentsFormat",["$window","_Format",function(a,b){return{restrict:"A",require:"ngModel",link:function(a,c,d,e){b(d.paymentsFormat,c,e)}}}]),angular.module("angularPayments").factory("_Validate",["Cards","Common","$parse",function(a,b,c){var d=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1},e=function(a){var b,c,d,e,f,g;for(d=!0,e=0,c=(a+"").split("").reverse(),f=0,g=c.length;g>f;f++)b=c[f],b=parseInt(b,10),(d=!d)&&(b*=2),b>9&&(b-=9),e+=b;return e%10===0},f={};return f.cvc=function(b,e,f,g){var h,i;if(null==b||0==b.length)return!0;if(!/^\d+$/.test(b))return!1;var j;if(g.paymentsTypeModel){var k=c(g.paymentsTypeModel);j=k(f)}return j?(h=b.length,d.call(null!=(i=a.fromType(j))?i.cvcLength:void 0,h)>=0):b.length>=3&&b.length<=4},f.card=function(b,f,g,h){var i,j,k;h.paymentsTypeModel&&(k=c(h.paymentsTypeModel));var l=function(){k&&k.assign(g,null),f.$card=null};return null==b||0==b.length?(l(),!0):(b=(b+"").replace(/\s+|-/g,""),/^\d+$/.test(b)&&(i=a.fromNumber(b))?(f.$card=angular.copy(i),k&&k.assign(g,i.type),j=b.length,ret=d.call(i.length,j)>=0&&(i.luhn===!1||e(b)),ret):(l(),!1))},f.expiry=function(a){if(null==a||0==a.length)return!0;obj=b.parseExpiry(a),month=obj.month,year=obj.year;var c,d,e;return month&&year&&/^\d+$/.test(month)&&/^\d+$/.test(year)&&parseInt(month,10)<=12?(2===year.length&&(e=(new Date).getFullYear(),e=e.toString().slice(0,2),year=e+year),d=new Date(year,month),c=new Date,d.setMonth(d.getMonth()-1),d.setMonth(d.getMonth()+1,1),d>c):!1},function(a,b,c,d,e){if(!f[a])throw types=Object.keys(f),errstr='Unknown type for validation: "'+a+'". ',errstr+='Should be one of: "'+types.join('", "')+'"';return f[a](b,c,d,e)}}]).factory("_ValidateWatch",["_Validate",function(a){var b={};return b.cvc=function(b,c,d,e){e.paymentsTypeModel&&d.$watch(e.paymentsTypeModel,function(f,g){if(f!=g){var h=a(b,c.$modelValue,c,d,e);c.$setValidity(b,h)}})},function(a,c,d,e){return b[a]?b[a](a,c,d,e):void 0}}]).directive("paymentsValidate",["$window","_Validate","_ValidateWatch",function(a,b,c){return{restrict:"A",require:"ngModel",link:function(a,d,e,f){var g=e.paymentsValidate;c(g,f,a,e);var h=function(c){var d=b(g,c,f,a,e);return f.$setValidity(g,d),d?c:void 0};f.$formatters.push(h),f.$parsers.push(h)}}}]),angular.module("angularPayments").directive("stripeForm",["$window","$parse","Common",function(a,b,c){return _getDataToSend=function(a){var b=["number","expMonth","expYear","cvc","name","addressLine1","addressLine2","addressCity","addressState","addressZip","addressCountry"],c=function(a){return a.replace(/([A-Z])/g,function(a){return"_"+a.toLowerCase()})},d={};for(i in b)a.hasOwnProperty(b[i])&&(d[c(b[i])]=angular.copy(a[b[i]]));return d.number=(d.number||"").replace(/ /g,""),d},{restrict:"A",link:function(b,d,e){if(!a.Stripe)throw"stripeForm requires that you have stripe.js installed. Include https://js.stripe.com/v2/ into your html.";var f=angular.element(d);f.bind("submit",function(){expMonthUsed=b.expMonth?!0:!1,expYearUsed=b.expYear?!0:!1,expMonthUsed&&expYearUsed||(exp=c.parseExpiry(b.expiry),b.expMonth=exp.month,b.expYear=exp.year);var d=f.find("button");d.prop("disabled",!0),f.hasClass("ng-valid")?a.Stripe.createToken(_getDataToSend(b),function(){var a=arguments;b.$apply(function(){b[e.stripeForm].apply(b,a)}),d.prop("disabled",!1)}):(b.$apply(function(){b[e.stripeForm].apply(b,[400,{error:"Invalid form submitted."}])}),d.prop("disabled",!1)),b.expMonth=null,b.expYear=null})}}}]); \ No newline at end of file +/*! angular-payments 01-09-2015 */ +angular.module("angularPayments",[]),angular.module("angularPayments").factory("Common",[function(){var a={};return a.parseExpiry=function(a){var b,c,d,e;return a=a||"",a=a.replace(/\s/g,""),e=a.split("/",2),b=e[0],d=e[1],2===(null!=d?d.length:void 0)&&/^\d+$/.test(d)&&(c=(new Date).getFullYear(),c=c.toString().slice(0,2),d=c+d),b=parseInt(b,10),d=parseInt(d,10),{month:b,year:d}},a}]),angular.module("angularPayments").factory("Cards",[function(){var a=/(\d{1,4})/g,b=/(?:^|\s)(\d{4})$/,c=[{type:"maestro",pattern:/^(5018|5020|5038|6304|6759|676[1-3])/,format:a,inputFormat:b,length:[12,13,14,15,16,17,18,19],cvcLength:[3],luhn:!0},{type:"dinersclub",pattern:/^(36|38|30[0-5])/,format:a,inputFormat:b,length:[14],cvcLength:[3],luhn:!0},{type:"laser",pattern:/^(6706|6771|6709)/,format:a,inputFormat:b,length:[16,17,18,19],cvcLength:[3],luhn:!0},{type:"jcb",pattern:/^35/,format:a,inputFormat:b,length:[16],cvcLength:[3],luhn:!0},{type:"unionpay",pattern:/^62/,format:a,inputFormat:b,length:[16,17,18,19],cvcLength:[3],luhn:!1},{type:"discover",pattern:/^(6011|65|64[4-9]|622)/,format:a,inputFormat:b,length:[16],cvcLength:[3],luhn:!0},{type:"mastercard",pattern:/^5[1-5]/,format:a,inputFormat:b,length:[16],cvcLength:[3],luhn:!0},{type:"amex",pattern:/^3[47]/,format:/(\d{1,4})(\d{1,6})?(\d{1,5})?/,inputFormat:/^(\d{4}|\d{4}\s\d{6})$/,length:[15],cvcLength:[3,4],luhn:!0},{type:"visa",pattern:/^4/,format:a,inputFormat:b,length:[13,14,15,16],cvcLength:[3],luhn:!0}],d=function(a){var b,d,e;for(a=(a+"").replace(/\D/g,""),d=0,e=c.length;e>d;d++)if(b=c[d],b.pattern.test(a))return b},e=function(a){var b,d,e;for(d=0,e=c.length;e>d;d++)if(b=c[d],b.type===a)return b};return{fromNumber:function(a){return d(a)},fromType:function(a){return e(a)},defaultFormat:function(){return a},defaultInputFormat:function(){return b}}}]),angular.module("angularPayments").factory("_Format",["Cards","Common","$filter",function(a,b,c){var d={},e=function(a){var b;return null!=a.prop("selectionStart")&&a.prop("selectionStart")!==a.prop("selectionEnd")?!0:("undefined"!=typeof document&&null!==document&&null!=(b=document.selection)&&"function"==typeof b.createRange?b.createRange().text:void 0)?!0:!1},f=function(b){var c,d,e,f,g,h,i;if(e=String.fromCharCode(b.which),c=angular.element(b.currentTarget),i=c.val(),d=a.fromNumber(i+e),f=(i.replace(/\D/g,"")+e).length,h=16,d&&(h=d.length[d.length.length-1]),!(f>=h)){if(!/^\d+$/.test(e)&&!b.meta&&b.keyCode>=46)return void b.preventDefault();if(null==c.prop("selectionStart")||c.prop("selectionStart")===i.length)return g=a.defaultInputFormat(),d&&(g=d.inputFormat),g.test(i)?(b.preventDefault(),c.val(i+" "+e)):g.test(i+e)?(b.preventDefault(),c.val(i+e+" ")):void 0}},g=function(b){var c,d,f,g;c=angular.element(b.currentTarget),f=String.fromCharCode(b.which),/^\d+$/.test(f)&&(e(c)||(g=(c.val()+f).replace(/\D/g,""),d=a.fromNumber(g),d?g.length<=d.length[d.length.length-1]||b.preventDefault():g.length<=16||b.preventDefault()))},h=function(a){var b,c;return b=angular.element(a.currentTarget),c=b.val(),a.meta||8!==a.which||null!=b.prop("selectionStart")&&b.prop("selectionStart")!==c.length?void 0:/\d\s$/.test(c)&&!a.meta&&a.keyCode>=46?(a.preventDefault(),b.val(c.replace(/\d\s$/,""))):/\s\d?$/.test(c)?(a.preventDefault(),b.val(c.replace(/\s\d?$/,""))):void 0},i=function(b){var c,d,e,f;return(c=a.fromNumber(b))?(e=c.length[c.length.length-1],b=b.replace(/\D/g,""),b=b.slice(0,+e+1||9e9),c.format.global?null!=(f=b.match(c.format))?f.join(" "):void 0:(d=c.format.exec(b),null!=d&&d.shift(),null!=d?d.join(" "):void 0)):b},j=function(a){return setTimeout(function(){var b,c;return b=angular.element(a.target),c=b.val(),c=i(c),b.val(c)})},k=function(a){return null!=a?a.replace(/\s/g,""):a};d.card=function(a,b){a.bind("keypress",g),a.bind("keypress",f),a.bind("keydown",h),a.bind("paste",j),b.$parsers.push(k),b.$formatters.push(i)};var l=function(a){var b,c,d;return b=angular.element(a.currentTarget),c=String.fromCharCode(a.which),!/^\d+$/.test(c)&&!a.meta&&a.keyCode>=46?void a.preventDefault():(d=b.val()+c,d.length<=4?void 0:void a.preventDefault())};d.cvc=function(a){a.bind("keypress",l)};var m=function(a){var b,c,d;return b=angular.element(a.currentTarget),c=String.fromCharCode(a.which),!/^\d+$/.test(c)&&!a.meta&&a.keyCode>=46?void a.preventDefault():e(b)?void 0:(d=b.val()+c,d=d.replace(/\D/g,""),d.length>6?void a.preventDefault():void 0)},n=function(a){var b,c,d;return c=String.fromCharCode(a.which),!/^\d+$/.test(c)&&!a.meta&&a.keyCode>=46?void a.preventDefault():(b=angular.element(a.currentTarget),d=b.val()+c,/^\d$/.test(d)&&"0"!==d&&"1"!==d?(a.preventDefault(),b.val("0"+d+" / ")):/^\d\d$/.test(d)?(a.preventDefault(),b.val(""+d+" / ")):void 0)},o=function(a){var b,c,d;return c=String.fromCharCode(a.which),!/^\d+$/.test(c)&&!a.meta&&a.keyCode>=46?void 0:(b=angular.element(a.currentTarget),d=b.val(),/^\d\d$/.test(d)?b.val(""+d+" / "):void 0)},p=function(a){var b,c,d;return c=String.fromCharCode(a.which),"/"===c?(b=angular.element(a.currentTarget),d=b.val(),/^\d$/.test(d)&&"0"!==d?b.val("0"+d+" / "):void 0):void 0},q=function(a){var b,c;if(!a.meta&&(b=angular.element(a.currentTarget),c=b.val(),8===a.which&&(null==b.prop("selectionStart")||b.prop("selectionStart")===c.length)))return/\d(\s|\/)+$/.test(c)?(a.preventDefault(),b.val(c.replace(/\d(\s|\/)*$/,""))):/\s\/\s?\d?$/.test(c)?(a.preventDefault(),b.val(c.replace(/\s\/\s?\d?$/,""))):void 0},r=function(a){if(null!=a){var d=b.parseExpiry(a),e=new Date(d.year,d.month-1);return c("date")(e,"MM/yyyy")}return null},s=function(a){if(null!=a){var d=b.parseExpiry(a),e=new Date(d.year,d.month-1);return c("date")(e,"MM / yyyy")}return null};return d.expiry=function(a,b){a.bind("keypress",m),a.bind("keypress",n),a.bind("keypress",p),a.bind("keypress",o),a.bind("keydown",q),b.$parsers.push(r),b.$formatters.push(s)},function(a,b,c){if(!d[a])throw types=Object.keys(d),errstr='Unknown type for formatting: "'+a+'". ',errstr+='Should be one of: "'+types.join('", "')+'"',errstr;return d[a](b,c)}}]).directive("paymentsFormat",["$window","_Format",function(a,b){return{restrict:"A",require:"ngModel",link:function(a,c,d,e){b(d.paymentsFormat,c,e)}}}]),angular.module("angularPayments").factory("_Validate",["Cards","Common","$parse",function(a,b,c){var d=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1},e=function(a){var b,c,d,e,f,g;for(d=!0,e=0,c=(a+"").split("").reverse(),f=0,g=c.length;g>f;f++)b=c[f],b=parseInt(b,10),(d=!d)&&(b*=2),b>9&&(b-=9),e+=b;return e%10===0},f={};return f.cvc=function(b,e,f,g){var h,i;if(null==b||0==b.length)return!0;if(!/^\d+$/.test(b))return!1;var j;if(g.paymentsTypeModel){var k=c(g.paymentsTypeModel);j=k(f)}return j?(h=b.length,d.call(null!=(i=a.fromType(j))?i.cvcLength:void 0,h)>=0):b.length>=3&&b.length<=4},f.card=function(b,f,g,h){var i,j,k;h.paymentsTypeModel&&(k=c(h.paymentsTypeModel));var l=function(){k&&k.assign(g,null),f.$card=null};return null==b||0==b.length?(l(),!0):(b=(b+"").replace(/\s+|-/g,""),/^\d+$/.test(b)&&(i=a.fromNumber(b))?(f.$card=angular.copy(i),k&&k.assign(g,i.type),j=b.length,d.call(i.length,j)>=0&&(i.luhn===!1||e(b))):(l(),!1))},f.expiry=function(a){var c,d,e,f;return null==a||0==a.length?!0:(c=b.parseExpiry(a),c.month&&c.year&&/^\d+$/.test(c.month)&&/^\d+$/.test(c.year)&&parseInt(c.month,10)<=12?(2===c.year.length&&(f=(new Date).getFullYear(),f=f.toString().slice(0,2),c.year=f+c.year),e=new Date(c.year,c.month),d=new Date,e.setMonth(e.getMonth()-1),e.setMonth(e.getMonth()+1,1),e>d):!1)},function(a,b,c,d,e){if(!f[a])throw types=Object.keys(f),errstr='Unknown type for validation: "'+a+'". ',errstr+='Should be one of: "'+types.join('", "')+'"',errstr;return f[a](b,c,d,e)}}]).factory("_ValidateWatch",["_Validate",function(a){var b={};return b.cvc=function(b,c,d,e){e.paymentsTypeModel&&d.$watch(e.paymentsTypeModel,function(f,g){if(f!=g){var h=a(b,c.$modelValue,c,d,e);c.$setValidity(b,h)}})},function(a,c,d,e){return b[a]?b[a](a,c,d,e):void 0}}]).directive("paymentsValidate",["$window","_Validate","_ValidateWatch",function(a,b,c){return{restrict:"A",require:"ngModel",link:function(a,d,e,f){var g=e.paymentsValidate;c(g,f,a,e);var h=function(c){var d=b(g,c,f,a,e);return f.$setValidity(g,d),d?c:void 0};f.$formatters.push(h),f.$parsers.push(h)}}}]),angular.module("angularPayments").directive("stripeForm",["$window","$parse","Common",function(a,b,c){var d=function(a){var b=["number","expMonth","expYear","cvc","name","addressLine1","addressLine2","addressCity","addressState","addressZip","addressCountry"],c=function(a){return a.replace(/([A-Z])/g,function(a){return"_"+a.toLowerCase()})},d={};for(var e in b)a.hasOwnProperty(b[e])&&(d[c(b[e])]=angular.copy(a[b[e]]));return d.number=(d.number||"").replace(/ /g,""),d};return{restrict:"A",link:function(b,e,f){if(!a.Stripe)throw"stripeForm requires that you have stripe.js installed. Include https://js.stripe.com/v2/ into your html.";var g=angular.element(e);g.bind("submit",function(){var e=b.expMonth?!0:!1,h=b.expYear?!0:!1;if(!e||!h){var i=c.parseExpiry(b.expiry);b.expMonth=i.month,b.expYear=i.year}var j=g.find("button");j.prop("disabled",!0),g.hasClass("ng-valid")?a.Stripe.createToken(d(b),function(){var a=arguments;b.$apply(function(){b[f.stripeForm].apply(b,a)}),j.prop("disabled",!1)}):(b.$apply(function(){b[f.stripeForm].apply(b,[400,{error:"Invalid form submitted."}])}),j.prop("disabled",!1)),b.expMonth=null,b.expYear=null})}}}]); \ No newline at end of file diff --git a/src/cards.js b/src/cards.js index 7b7d1e5..bb4b008 100644 --- a/src/cards.js +++ b/src/cards.js @@ -5,7 +5,7 @@ angular.module('angularPayments') var defaultFormat = /(\d{1,4})/g; var defaultInputFormat = /(?:^|\s)(\d{4})$/; - var cards = [ + var cards = [ { type: 'maestro', pattern: /^(5018|5020|5038|6304|6759|676[1-3])/, @@ -96,7 +96,7 @@ angular.module('angularPayments') } } - } + }; var _fromType = function(type) { var card, i, len; diff --git a/src/common.js b/src/common.js index a486efc..7f843e1 100644 --- a/src/common.js +++ b/src/common.js @@ -9,7 +9,7 @@ angular.module('angularPayments') ret['parseExpiry'] = function(value){ var month, prefix, year, _ref; - value = value || '' + value = value || ''; value = value.replace(/\s/g, ''); _ref = value.split('/', 2), month = _ref[0], year = _ref[1]; @@ -27,7 +27,7 @@ angular.module('angularPayments') month: month, year: year }; - } + }; return ret; diff --git a/src/form.js b/src/form.js index 121c1f2..d2ea387 100644 --- a/src/form.js +++ b/src/form.js @@ -10,23 +10,23 @@ angular.module('angularPayments') // filter valid stripe-values from scope and convert them from camelCase to snake_case - _getDataToSend = function(data){ + var _getDataToSend = function(data){ var possibleKeys = ['number', 'expMonth', 'expYear', 'cvc', 'name','addressLine1', 'addressLine2', 'addressCity', 'addressState', 'addressZip', - 'addressCountry'] + 'addressCountry']; var camelToSnake = function(str){ return str.replace(/([A-Z])/g, function(m){ return "_"+m.toLowerCase(); }); - } + }; var ret = {}; - for(i in possibleKeys){ + for(var i in possibleKeys){ if(data.hasOwnProperty(possibleKeys[i])){ ret[camelToSnake(possibleKeys[i])] = angular.copy(data[possibleKeys[i]]); } @@ -35,7 +35,7 @@ angular.module('angularPayments') ret['number'] = (ret['number'] || '').replace(/ /g,''); return ret; - } + }; return { restrict: 'A', @@ -49,13 +49,13 @@ angular.module('angularPayments') form.bind('submit', function() { - expMonthUsed = scope.expMonth ? true : false; - expYearUsed = scope.expYear ? true : false; + var expMonthUsed = scope.expMonth ? true : false; + var expYearUsed = scope.expYear ? true : false; if(!(expMonthUsed && expYearUsed)){ - exp = Common.parseExpiry(scope.expiry) - scope.expMonth = exp.month - scope.expYear = exp.year + var exp = Common.parseExpiry(scope.expiry); + scope.expMonth = exp.month; + scope.expYear = exp.year; } var button = form.find('button'); diff --git a/src/format.js b/src/format.js index 68455cf..5f1151a 100644 --- a/src/format.js +++ b/src/format.js @@ -3,7 +3,7 @@ angular.module('angularPayments') .factory('_Format',['Cards', 'Common', '$filter', function(Cards, Common, $filter){ - var _formats = {} + var _formats = {}; var _hasTextSelected = function($target) { var ref; @@ -169,12 +169,15 @@ angular.module('angularPayments') ctrl.$parsers.push(_parseCardNumber); ctrl.$formatters.push(_getFormattedCardNumber); - } + }; // cvc - _formatCVC = function(e){ + var _formatCVC = function(e){ + + var $target, digit, val; + $target = angular.element(e.currentTarget); digit = String.fromCharCode(e.which); @@ -191,15 +194,15 @@ angular.module('angularPayments') e.preventDefault(); return; } - } + }; _formats['cvc'] = function(elem){ elem.bind('keypress', _formatCVC) - } + }; // expiry - _restrictExpiry = function(e) { + var _restrictExpiry = function(e) { var $target, digit, value; $target = angular.element(e.currentTarget); @@ -223,7 +226,7 @@ angular.module('angularPayments') } }; - _formatExpiry = function(e) { + var _formatExpiry = function(e) { var $target, digit, val; digit = String.fromCharCode(e.which); @@ -247,7 +250,7 @@ angular.module('angularPayments') } }; - _formatForwardExpiry = function(e) { + var _formatForwardExpiry = function(e) { var $target, digit, val; digit = String.fromCharCode(e.which); @@ -264,7 +267,7 @@ angular.module('angularPayments') } }; - _formatForwardSlash = function(e) { + var _formatForwardSlash = function(e) { var $target, slash, val; slash = String.fromCharCode(e.which); @@ -281,7 +284,7 @@ angular.module('angularPayments') } }; - _formatBackExpiry = function(e) { + var _formatBackExpiry = function(e) { var $target, value; if (e.meta) { @@ -338,7 +341,7 @@ angular.module('angularPayments') ctrl.$parsers.push(_parseExpiry); ctrl.$formatters.push(_getFormattedExpiry); - } + }; return function(type, elem, ctrl){ if(!_formats[type]){ diff --git a/src/validate.js b/src/validate.js index ecf412c..42b8e2c 100644 --- a/src/validate.js +++ b/src/validate.js @@ -4,7 +4,7 @@ angular.module('angularPayments') .factory('_Validate', ['Cards', 'Common', '$parse', function(Cards, Common, $parse){ - var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; } + var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; var _luhnCheck = function(num) { var digit, digits, odd, sum, i, len; @@ -56,7 +56,7 @@ angular.module('angularPayments') } else { return cvc.length >= 3 && cvc.length <= 4; } - } + }; _validators['card'] = function(num, ctrl, scope, attr){ var card, ref, typeModel; @@ -98,51 +98,45 @@ angular.module('angularPayments') typeModel.assign(scope, card.type); } - ret = (ref = num.length, __indexOf.call(card.length, ref) >= 0) && (card.luhn === false || _luhnCheck(num)); - - return ret; - } + return (ref = num.length, __indexOf.call(card.length, ref) >= 0) && (card.luhn === false || _luhnCheck(num)); + }; _validators['expiry'] = function(val){ + var obj, currentTime, expiry, prefix; // valid if empty - let ng-required handle empty if(val == null || val.length == 0) return true; obj = Common.parseExpiry(val); - month = obj.month; - year = obj.year; - - var currentTime, expiry, prefix; - - if (!(month && year)) { + if (!(obj.month && obj.year)) { return false; } - if (!/^\d+$/.test(month)) { + if (!/^\d+$/.test(obj.month)) { return false; } - if (!/^\d+$/.test(year)) { + if (!/^\d+$/.test(obj.year)) { return false; } - if (!(parseInt(month, 10) <= 12)) { + if (!(parseInt(obj.month, 10) <= 12)) { return false; } - if (year.length === 2) { + if (obj.year.length === 2) { prefix = (new Date).getFullYear(); prefix = prefix.toString().slice(0, 2); - year = prefix + year; + obj.year = prefix + obj.year; } - expiry = new Date(year, month); + expiry = new Date(obj.year, obj.month); currentTime = new Date; expiry.setMonth(expiry.getMonth() - 1); expiry.setMonth(expiry.getMonth() + 1, 1); return expiry > currentTime; - } + }; return function(type, val, ctrl, scope, attr){ if(!_validators[type]){ @@ -161,7 +155,7 @@ angular.module('angularPayments') .factory('_ValidateWatch', ['_Validate', function(_Validate){ - var _validatorWatches = {} + var _validatorWatches = {}; _validatorWatches['cvc'] = function(type, ctrl, scope, attr){ if(attr.paymentsTypeModel) { @@ -172,7 +166,7 @@ angular.module('angularPayments') } }); } - } + }; return function(type, ctrl, scope, attr){ if(_validatorWatches[type]){