Merge pull request #1609 from Arkni/transformation-layer

Core: Added transformation/normalization layer
This commit is contained in:
Markus Staab
2015-10-25 20:49:35 +01:00
4 changed files with 109 additions and 3 deletions

View File

@@ -626,6 +626,22 @@ $.extend( $.validator, {
val = this.elementValue( element ), val = this.elementValue( element ),
result, method, rule; result, method, rule;
// If a normalizer is defined for this element, then
// call it to retreive the changed value instead
// of using the real one.
// Note that `this` in the normalizer is `element`.
if ( typeof rules.normalizer === "function" ) {
val = rules.normalizer.call( element, val );
if ( typeof val !== "string" ) {
throw new TypeError( "The normalizer should return a string value." );
}
// Delete the normalizer from rules to avoid treating
// it as a pre-defined method.
delete rules.normalizer;
}
for ( method in rules ) { for ( method in rules ) {
rule = { method: method, parameters: rules[ method ] }; rule = { method: method, parameters: rules[ method ] };
try { try {
@@ -860,7 +876,7 @@ $.extend( $.validator, {
// meta-characters that should be escaped in order to be used with JQuery // meta-characters that should be escaped in order to be used with JQuery
// as a literal part of a name/id or any selector. // as a literal part of a name/id or any selector.
escapeCssMeta: function( string ) { escapeCssMeta: function( string ) {
return string.replace( /(!|"|#|\$|%|&|'|\(|\)|\*|\+|,|\.|\/|:|;|<|=|>|\?|@|\[|\\|\]|\^|`|\{|\||\}|~)/g, "\\$1"); return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
}, },
idOrName: function( element ) { idOrName: function( element ) {
@@ -1103,7 +1119,7 @@ $.extend( $.validator, {
// evaluate parameters // evaluate parameters
$.each( rules, function( rule, parameter ) { $.each( rules, function( rule, parameter ) {
rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter; rules[ rule ] = $.isFunction( parameter ) && rule !== "normalizer" ? parameter( element ) : parameter;
} ); } );
// clean number parameters // clean number parameters

View File

@@ -35,6 +35,7 @@
"stop": false, "stop": false,
"test": false, "test": false,
"TestHelpers": true, "TestHelpers": true,
"throws": false,
"JSHINT": false "JSHINT": false
} }
} }

View File

@@ -72,6 +72,7 @@
<label id="errorFirstnamec" for="firstnamec" class="error">error for firstname</label> <label id="errorFirstnamec" for="firstnamec" class="error">error for firstname</label>
<input title="buga" name="lastname" id="lastnamec"> <input title="buga" name="lastname" id="lastnamec">
<input name="username" id="usernamec"> <input name="username" id="usernamec">
<input id="urlc" type="text" name="urlc">
</form> </form>
<form id="userForm"> <form id="userForm">
<input type="text" data-rule-required="true" name="username" id="username"> <input type="text" data-rule-required="true" name="username" id="username">
@@ -379,7 +380,7 @@
</form> </form>
<form id="testForm21"> <form id="testForm21">
<label for="testForm21!#$%&'()*+,./:;<=>?@[\]^`{|}~">Input text</label> <label for="testForm21!#$%&'()*+,./:;<=>?@[\]^`{|}~">Input text</label>
<input type="text" name="testForm21!#$%&'()*+,./:;<=>?@[\]^`{|}~\" id="testForm21!#$%&'()*+,./:;<=>?@[\]^`{|}~" required minlength="15"> <input type="text" name="testForm21!#$%&'()*+,./:;<=>?@[\]^`{|}~" id="testForm21!#$%&'()*+,./:;<=>?@[\]^`{|}~" required minlength="15">
</form> </form>
</div> </div>
</body> </body>

View File

@@ -305,3 +305,91 @@ test( "rules(), rangelength attribute as array", function() {
rangelength: [ 2, 3 ] rangelength: [ 2, 3 ]
} ); } );
} ); } );
test( "rules(), normalizer", function() {
var username = $( "#usernamec" ),
urlc = $( "#urlc" ),
lastname = $( "#lastnamec" ),
v;
username.val( "\t\t \r" );
urlc.val( "" );
v = $( "#testForm1clean" ).validate( {
rules: {
username: {
required: true,
// Using the normalizer to trim the value of the element
// before validating it.
normalizer: function( value ) {
equal( this, username[ 0 ], "`this` in the normalizer should be the username element." );
// Trim the value of the input
return $.trim( value );
}
},
urlc: {
required: true,
url: true,
// Using the normalizer to append https:// if it's not
// present on the input value
normalizer: function( value ) {
equal( this, urlc[ 0 ], "`this` in the normalizer should be the urlc element." );
var url = value;
// Check if it doesn't start with http:// or https:// or ftp://
if ( url && url.substr( 0, 7 ) !== "http://" &&
url.substr( 0, 8 ) !== "https://" &&
url.substr( 0, 6 ) !== "ftp://" ) {
// then prefix with http:// or even https://
url = "https://" + url;
}
// Return the new url
return url;
}
},
lastname: {
required: true,
// Using the normalizer to trim the value of the element
// before validating it.
normalizer: function( value ) {
equal( this, lastname[ 0 ], "`this` in the normalizer should be the lastname element." );
// Return null in order to make sure a exception is thrown
// when normalizer returns a non string value.
value = null;
return value;
}
}
}
} );
// Validate only the username and the url elements.
username.valid();
equal( v.invalidElements()[ 0 ], username[ 0 ], "The username should be invalid" );
urlc.valid();
equal( v.invalidElements()[ 0 ], urlc[ 0 ], "The url should be invalid" );
equal( v.numberOfInvalids(), 2, "There is two invalid elements" );
username.val( "something" );
urlc.val( "google.com" );
username.trigger( "keyup" );
urlc.trigger( "keyup" );
equal( v.numberOfInvalids(), 0, "All elements are valid" );
equal( v.size(), 0, "All elements are valid" );
equal( v.isValidElement( urlc[ 0 ] ), true, "The url element should be valid" );
// Validate the lastname element, which will throw an exception
throws( function() {
v.check( lastname[ 0 ] );
}, function( err ) {
return err.name === "TypeError" && err.message === "The normalizer should return a string value.";
}, "This should throw a TypeError exception." );
} );