diff --git a/form-validator/color.js b/form-validator/color.js index 198b97a..2a891e4 100644 --- a/form-validator/color.js +++ b/form-validator/color.js @@ -6,4 +6,4 @@ * @author Victor Jonsson, http://victorjonsson.se * @license MIT */ -!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof module&&module.exports?module.exports=b(require("jquery")):b(a.jQuery)}(this,function(a){!function(a){a.formUtils.registerLoadedModule("color");var b=function(a){return/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/.test(a)?Number(a):NaN},c=function(a){return a>0&&a<1};a.formUtils.addValidator({name:"hex",validatorFunction:function(a,b){if("true"===b.valAttr("allow-transparent")&&"transparent"===a)return!0;var c="#"===a[0];if(!c)return!1;var d=4===a.length||7===a.length;if(d){var e=/[0-9a-f]/i,f=a.slice(1).split(""),g=!0;return f.forEach(function(a){null===a.match(e)&&(g=!1)}),g}return!1},errorMessage:"",errorMessageKey:"badHex"}),a.formUtils.addValidator({name:"rgb",validatorFunction:function(a,b){if("true"===b.valAttr("allow-transparent")&&"transparent"===a)return!0;var c=a.replace(/ /g,""),d=/\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3}\)/i;if(c.match(d)){var e=c.replace(/\(/g,"").replace(/\)/g,""),f=e.split(","),g=!0;return f.forEach(function(a){var b=parseInt(a);(Number.isInteger(b)&&0<=b&&b<=255)===!1&&(g=!1)}),g}return!1},errorMessage:"",errorMessageKey:"badRgb"}),a.formUtils.addValidator({name:"rgba",validatorFunction:function(a,d){if("true"===d.valAttr("allow-transparent")&&"transparent"===a)return!0;var e=a.replace(/ /g,""),f=/\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0,1]{1}.?[0-9]*\)/i;if(e.match(f)){var g=e.replace(/\(/g,"").replace(/\)/g,""),h=g.split(","),i=!0;return h.forEach(function(a){var d=b(a);if(Number.isInteger(d)){var e=d>=0&&d<=255;e||(i=!1)}else c(d)||(i=!1)}),i}return!1},errorMessage:"",errorMessageKey:"badRgba"}),a.formUtils.addValidator({name:"hsl",validatorFunction:function(a,b){if("true"===b.valAttr("allow-transparent")&&"transparent"===a)return!0;var c,d=a.replace(/ /g,""),e=/\([0-9]{1,3},[0-9]{1,3}%,[0-9]{1,3}%\)/i;if(d.match(e)){var f=d.replace(/\(/g,"").replace(/\)/g,""),g=f.split(","),h=!0;return g.forEach(function(a,b){var d=parseInt(a);Number.isInteger(d)?0===b?(c=0<=d&&d<=360,c||(h=!1)):(c=0<=d&&d<=100,c||(h=!1)):h=!1}),h}return!1},errorMessage:"",errorMessageKey:"badHsl"}),a.formUtils.addValidator({name:"hsla",validatorFunction:function(a,c){if("true"===c.valAttr("allow-transparent")&&"transparent"===a)return!0;var d,e=a.replace(/ /g,""),f=/\([0-9]{1,3},[0-9]{1,3}%,[0-9]{1,3}%,[0,1]{1}.?[0-9]*\)/i;if(e.match(f)){var g=e.replace(/\(/g,"").replace(/\)/g,""),h=g.split(","),i=!0;return h.forEach(function(a,c){var e=b(a);Number.isInteger(e)?0===c?(d=0<=e&&e<=360,d||(i=!1)):(d=0<=e&&e<=100,d||(i=!1)):isNaN(e)?(e=parseInt(a),d=0<=e&&e<=100,d||(i=!1)):(d=0<=e&&e<=1,d||(i=!1))}),i}return!1},errorMessage:"",errorMessageKey:"badHsla"})}(a)}); \ No newline at end of file +!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof module&&module.exports?module.exports=b(require("jquery")):b(a.jQuery)}(this,function(a){!function(a){a.formUtils.registerLoadedModule("color");var b=function(a){return/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/.test(a)?Number(a):NaN},c=function(a){return a>0&&a<1},d=function(b){return Math.floor(b)===b&&a.isNumeric(b)};a.formUtils.addValidator({name:"hex",validatorFunction:function(a,b){if("true"===b.valAttr("allow-transparent")&&"transparent"===a)return!0;var c="#"===a[0];if(!c)return!1;var d=4===a.length||7===a.length;if(d){var e=/[0-9a-f]/i,f=a.slice(1).split(""),g=!0;return f.forEach(function(a){null===a.match(e)&&(g=!1)}),g}return!1},errorMessage:"",errorMessageKey:"badHex"}),a.formUtils.addValidator({name:"rgb",validatorFunction:function(a,b){if("true"===b.valAttr("allow-transparent")&&"transparent"===a)return!0;var c=a.replace(/ /g,""),e=/rgb\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3}\)/i;if(c.match(e)){var f=c.replace(/rgb/g,""),g=f.replace(/\(/g,"").replace(/\)/g,""),h=g.split(","),i=!0;return h.forEach(function(a){var b=parseInt(a,10);(d(b)&&0<=b&&b<=255)===!1&&(i=!1)}),i}return!1},errorMessage:"",errorMessageKey:"badRgb"}),a.formUtils.addValidator({name:"rgba",validatorFunction:function(a,e){if("true"===e.valAttr("allow-transparent")&&"transparent"===a)return!0;var f=a.replace(/ /g,""),g=/rgba\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0,1]?.?[0-9]*\)/i;if(f.match(g)){var h=f.replace(/rgba/g,""),i=h.replace(/\(/g,"").replace(/\)/g,""),j=i.split(","),k=!0;return j.forEach(function(a,e){var f=b(a);if(d(f)){var g=f>=0&&f<=255;g||(k=!1),k&&3===e&&(k=f>=0&&f<2)}else c(a)||(k=!1)}),k}return!1},errorMessage:"",errorMessageKey:"badRgba"}),a.formUtils.addValidator({name:"hsl",validatorFunction:function(a,b){if("true"===b.valAttr("allow-transparent")&&"transparent"===a)return!0;var c=a.replace(/ /g,""),e=/hsl\(-?[0-9]{1,3},[0-9]{1,3}%,[0-9]{1,3}%\)/i;if(c.match(e)){var f=c.replace(/hsl/g,""),g=f.replace(/\(/g,"").replace(/\)/g,""),h=g.split(","),i=!0;return h.forEach(function(a,b){var c=parseInt(a,10);if(d(c)){if(0!==b){var e=c>=0&&c<=100;e||(i=!1)}}else i=!1}),i}return!1},errorMessage:"",errorMessageKey:"badHsl"}),a.formUtils.addValidator({name:"hsla",validatorFunction:function(a,c){if("true"===c.valAttr("allow-transparent")&&"transparent"===a)return!0;var e,f=a.replace(/ /g,""),g=/hsla\(-?[0-9]{1,3},[0-9]{1,3}%,[0-9]{1,3}%,[0,1]?.?[0-9]*\)/i;if(f.match(g)){var h=f.replace(/hsla/g,""),i=h.replace(/\(/g,"").replace(/\)/g,""),j=i.split(","),k=!0;return j.forEach(function(a,c){var f=b(a),g=parseInt(a,10);d(f)?(0!==c&&3!==c&&(e=f>=0&&f<=100,e||(k=!1)),k&&3===c&&(k=f>=0&&f<2)):isNaN(f)&&d(g)?(e=g>=0&&g<=100,e||(k=!1)):(f=b(Number(a).toFixed(20)),e=f>=0&&f<=1,e||(k=!1))}),k}return!1},errorMessage:"",errorMessageKey:"badHsla"})}(a)}); \ No newline at end of file diff --git a/src/modules/color.js b/src/modules/color.js index ecd1f58..938dbab 100644 --- a/src/modules/color.js +++ b/src/modules/color.js @@ -31,6 +31,13 @@ return value > 0 && value < 1; }; + // workaround for PhantomJS + // https://github.com/ariya/phantomjs/issues/14014 + // can't use Number.isInteger + var isInteger = function(value) { + return Math.floor(value) === value && $.isNumeric(value); + }; + /** * Check HEX format */ @@ -77,16 +84,17 @@ } var removedSpace = val.replace(/ /g, ''); - var regex = /\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3}\)/i; + var regex = /rgb\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3}\)/i; if (removedSpace.match(regex)) { - var removeBrackets = removedSpace.replace(/\(/g, '').replace(/\)/g, ''); + var removeRgbCall = removedSpace.replace(/rgb/g, ''); + var removeBrackets = removeRgbCall.replace(/\(/g, '').replace(/\)/g, ''); var valueSliced = removeBrackets.split(','); var isValid = true; valueSliced.forEach(function(i) { - var parsedInt = parseInt(i); - if ((Number.isInteger(parsedInt) && 0 <= parsedInt && parsedInt <= 255) === false) { + var parsedInt = parseInt(i, 10); + if ((isInteger(parsedInt) && 0 <= parsedInt && parsedInt <= 255) === false) { isValid = false; } }); @@ -110,24 +118,27 @@ } var removedSpace = val.replace(/ /g, ''); - var regex = /\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0,1]{1}.?[0-9]*\)/i; + var regex = /rgba\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0,1]?.?[0-9]*\)/i; if (removedSpace.match(regex)) { - var removeBrackets = removedSpace.replace(/\(/g, '').replace(/\)/g, ''); + var removeRgbaCall = removedSpace.replace(/rgba/g, ''); + var removeBrackets = removeRgbaCall.replace(/\(/g, '').replace(/\)/g, ''); var valueSliced = removeBrackets.split(','); var isValid = true; - valueSliced.forEach(function(i) { + valueSliced.forEach(function(i, index) { var value = filterFloat(i); - if (Number.isInteger(value)) { + if (isInteger(value)) { var isInRange = value >= 0 && value <= 255; if (!isInRange) { isValid = false; } - } else { - if (!isBetween0and1(value)) { - isValid = false; + + if (isValid && index === 3) { + isValid = value >= 0 && value < 2; } + } else if (!isBetween0and1(i)) { + isValid = false; } }); return isValid; @@ -149,26 +160,21 @@ return true; } - var isInRange; var removedSpace = val.replace(/ /g, ''); - var regex = /\([0-9]{1,3},[0-9]{1,3}%,[0-9]{1,3}%\)/i; + var regex = /hsl\(-?[0-9]{1,3},[0-9]{1,3}%,[0-9]{1,3}%\)/i; if (removedSpace.match(regex)) { - var removeBrackets = removedSpace.replace(/\(/g, '').replace(/\)/g, ''); + var removeHslCall = removedSpace.replace(/hsl/g, ''); + var removeBrackets = removeHslCall.replace(/\(/g, '').replace(/\)/g, ''); var valueSliced = removeBrackets.split(','); var isValid = true; valueSliced.forEach(function(i, index) { - var parsedInt = parseInt(i); + var parsedInt = parseInt(i, 10); - if (Number.isInteger(parsedInt)) { - if (index === 0) { - isInRange = 0 <= parsedInt && parsedInt <= 360; - if (!isInRange) { - isValid = false; - } - } else { - isInRange = 0 <= parsedInt && parsedInt <= 100; + if (isInteger(parsedInt)) { + if (index !== 0) { + var isInRange = parsedInt >= 0 && parsedInt <= 100; if (!isInRange) { isValid = false; } @@ -198,46 +204,44 @@ var isInRange; var removedSpace = val.replace(/ /g, ''); - var regex = /\([0-9]{1,3},[0-9]{1,3}%,[0-9]{1,3}%,[0,1]{1}.?[0-9]*\)/i; + var regex = /hsla\(-?[0-9]{1,3},[0-9]{1,3}%,[0-9]{1,3}%,[0,1]?.?[0-9]*\)/i; if (removedSpace.match(regex)) { - var removeBrackets = removedSpace.replace(/\(/g, '').replace(/\)/g, ''); + var removeHslaCall = removedSpace.replace(/hsla/g, ''); + var removeBrackets = removeHslaCall.replace(/\(/g, '').replace(/\)/g, ''); var valueSliced = removeBrackets.split(','); var isValid = true; valueSliced.forEach(function(i, index) { var value = filterFloat(i); + var parsedInt = parseInt(i, 10); - if (Number.isInteger(value)) { - - if (index === 0) { - isInRange = 0 <= value && value <= 360; + if (isInteger(value)) { + if (index !== 0 && index !== 3) { + isInRange = value >= 0 && value <= 100; if (!isInRange) { isValid = false; } - } else { + } - isInRange = 0 <= value && value <= 100; - if (!isInRange) { - isValid = false; - } + if (isValid && index === 3) { + isValid = value >= 0 && value < 2; + } + } else if (isNaN(value) && isInteger(parsedInt)) { + isInRange = parsedInt >= 0 && parsedInt <= 100; + if (!isInRange) { + isValid = false; } } else { - if (isNaN(value)) { - // percent value - value = parseInt(i); - isInRange = 0 <= value && value <= 100; - if (!isInRange) { - isValid = false; - } - } else { - isInRange = 0 <= value && value <= 1; - if (!isInRange) { - isValid = false; - } + value = filterFloat(Number(i).toFixed(20)); + + isInRange = value >= 0 && value <= 1; + if (!isInRange) { + isValid = false; } } }); + return isValid; } diff --git a/test/qunit.html b/test/qunit.html index 8248d0e..1f006b6 100644 --- a/test/qunit.html +++ b/test/qunit.html @@ -1124,11 +1124,154 @@ }); }); + test("Color Hex validation", function() { + + clearForm(); + + var links = [ + {val: '#0000FF', isValid: true}, + {val: '#00F', isValid: true}, + {val: '123', isValid: false}, + {val: '112233', isValid: false}, + {val: '#4567', isValid: false}, + {val: input('transparent', {'allow-transparent': 'true'}), isValid: true}, + {val: 'transparent', isValid: false} + ]; + + $.each(links, function(i, obj) { + runTest(obj, 'hex'); + }); + }); + + test("Color Rgb validation", function() { + + clearForm(); + + var links = [ + {val: 'rgb(255,255,255)', isValid: true}, + {val: 'rgb( 255 , 255 , 255 )', isValid: true}, + {val: 'rgb( 255, 255, 255 )', isValid: true}, + {val: 'rgb(255,255,255)', isValid: true}, + + + {val: 'rgb(-10,255,255)', isValid: false}, + {val: '255255255', isValid: false}, + {val: 'rgb(255,255,256)', isValid: false}, + + + {val: input('transparent', {'allow-transparent': 'true'}), isValid: true}, + {val: 'transparent', isValid: false} + ]; + + $.each(links, function(i, obj) { + runTest(obj, 'rgb'); + }); + }); + + test("Color Rgba validation", function() { + + clearForm(); + + var links = [ + {val: 'rgba(255,255,255,1)', isValid: true}, + {val: 'rgba( 255 , 255 , 255 , 1 )', isValid: true}, + {val: 'rgba( 255 , 255 , 255 , 1 )', isValid: true}, + {val: 'rgba(255,255,255,1)', isValid: true}, + {val: 'rgba(255,255,255,0)', isValid: true}, + {val: 'rgba(255,255,255,1)', isValid: true}, + {val: 'rgba(255,255,255,0.5)', isValid: true}, + {val: 'rgba(255,255,255,.5)', isValid: true}, + {val: 'rgba(255,255,255,.524141)', isValid: true}, + {val: 'rgba(255,255,255,2)', isValid: false}, + {val: 'rgba(255,255,255,-1)', isValid: false}, + {val: 'rgba(255,255,255,1.000000000001)', isValid: false}, + {val: 'rgba(255,255,255,-0.5)', isValid: false}, + {val: 'rgba(255,255,255,2.3)', isValid: false}, + {val: 'rgba(-10,255,255,1)', isValid: false}, + {val: '2552552551', isValid: false}, + {val: 'rgba(255,255,256),1', isValid: false}, + {val: '0000FF', isValid: false}, + {val: input('transparent', {'allow-transparent': 'true'}), isValid: true}, + {val: 'transparent', isValid: false} + ]; + + $.each(links, function(i, obj) { + runTest(obj, 'rgba'); + }); + }); + + test("Color Hsl validation", function() { + + clearForm(); + + var links = [ + {val: 'hsl(120,50%,50%)', isValid: true}, + {val: 'hsl( 120 , 50% , 50% )', isValid: true}, + {val: 'hsl( 120, 50%, 50% )', isValid: true}, + {val: 'hsl(-120,50%,50%)', isValid: true}, + {val: 'hsl(480,50%,50%)', isValid: true}, + + {val: 'hsl(10,-50%,50%)', isValid: false}, + {val: 'hsl(10,50%,-50%)', isValid: false}, + {val: '120,50%,50%', isValid: false}, + {val: 'hsl(120,100%,101%)', isValid: false}, + {val: 'hsl(50%, 50%, 100%)', isValid: false}, + {val: 'hsl(120, 50, 100%)', isValid: false}, + {val: 'hsl(120, 50%, 100)', isValid: false}, + + {val: input('transparent', {'allow-transparent': 'true'}), isValid: true}, + {val: 'transparent', isValid: false} + ]; + + $.each(links, function(i, obj) { + runTest(obj, 'hsl'); + }); + }); + + test("Color Hsla validation", function() { + + clearForm(); + + var links = [ + {val: 'hsla(120,50%,50%,1)', isValid: true}, + {val: 'hsla( 120 , 50% , 50%, 1 )', isValid: true}, + {val: 'hsla( 120, 50%, 50% , 1 )', isValid: true}, + {val: 'hsla(-120,50%,50%,1)', isValid: true}, + {val: 'hsla(480,50%,50%,1)', isValid: true}, + {val: 'hsla(120,50%,100%,0)', isValid: true}, + {val: 'hsla(120,50%,100%,1)', isValid: true}, + {val: 'hsla(120,50%,100%,0.5)', isValid: true}, + {val: 'hsla(120,50%,100%,.5)', isValid: true}, + {val: 'hsla(120,50%,100%,.524141)', isValid: true}, + + {val: 'hsla(120,50%,100%,50%)', isValid: false}, + {val: 'hsla(120,50%,100%,2)', isValid: false}, + {val: 'hsla(120,50%,100%,-1)', isValid: false}, + {val: 'hsla(120,50%,100%,1.000000000001)', isValid: false}, + {val: 'hsla(120,50%,100%,-0.5)', isValid: false}, + {val: 'hsla(120,50%,100%,2.3)', isValid: false}, + {val: 'hsla(10,-50%,50%,1)', isValid: false}, + {val: 'hsla(10,50%,-50%,1)', isValid: false}, + {val: '120,50%,50%,1', isValid: false}, + {val: 'hsla(120,100%,101%,1)', isValid: false}, + {val: 'hsla(50%, 50%, 100%,1)', isValid: false}, + {val: 'hsla(120, 50, 100%,1)', isValid: false}, + {val: 'hsla(120, 50%, 100,1)', isValid: false}, + + {val: input('transparent', {'allow-transparent': 'true'}), isValid: true}, + {val: 'transparent', isValid: false} + ]; + + $.each(links, function(i, obj) { + runTest(obj, 'hsla'); + }); + }); + // TODO: Write more tests... } $.validate({ - modules : 'security, location, sweden, file, date, sanitize, uk, poland', + modules : 'security, location, sweden, file, date, sanitize, uk, poland, color', onModulesLoaded: function( $form ) { if( window.console && window.console.log ) console.log('About to run all tests');