Browse Source

relax quantifier validation in regex extension

Robin Herbots 12 years ago
parent
commit
4f4ca5b059

+ 1 - 1
build.properties

@@ -7,7 +7,7 @@ distdir = dist
 
 build.major = 2
 build.minor = 3
-build.revision = 11
+build.revision = 12
 
 target = jquery.inputmask.bundle.js
 target.min = jquery.inputmask.bundle.min.js

+ 1 - 1
component.json

@@ -1,6 +1,6 @@
 {
     "name": "jquery.inputmask",
-    "version": "2.3.11",
+    "version": "2.3.12",
     "main": "./dist/jquery.inputmask.bundle.js",
     "dependencies": {
         "jquery": ">=1.5"

BIN
dist/jQuery.InputMask.2.3.11.nupkg


BIN
dist/jQuery.InputMask.2.3.12.nupkg


+ 39 - 18
dist/jquery.inputmask.bundle.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2013 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 2.3.11
+* Version: 2.3.12
 */
 
 (function ($) {
@@ -1512,7 +1512,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2013 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 2.3.11
+Version: 2.3.12
 
 Optional extensions on the jquery.inputmask base
 */
@@ -1614,7 +1614,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2012 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 2.3.11
+Version: 2.3.12
 
 Optional extensions on the jquery.inputmask base
 */
@@ -2091,7 +2091,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2013 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 2.3.11
+Version: 2.3.12
 
 Optional extensions on the jquery.inputmask base
 */
@@ -2258,7 +2258,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2013 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 2.3.11
+Version: 2.3.12
 
 Regex extensions on the jquery.inputmask base
 Allows for using regular expressions as a mask
@@ -2271,14 +2271,16 @@ Allows for using regular expressions as a mask
             repeat: "*",
             regex: null,
             regexTokens: null,
+            //Thx to https://github.com/slevithan/regex-colorizer for the tokenizer regex
             tokenizer: /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g,
+            quantifierFilter: /[0-9]+[^,]/,
             definitions: {
                 'r': {
                     validator: function (chrs, buffer, pos, strict, opts) {
 
                         function analyseRegex() {
                             var currentToken = {
-                                "quantifier": undefined,
+                                "isQuantifier": false,
                                 "matches": [],
                                 "isGroup": false
                             }, match, m, opengroups = [];
@@ -2289,12 +2291,11 @@ Allows for using regular expressions as a mask
                             while (match = opts.tokenizer.exec(opts.regex)) {
                                 m = match[0];
                                 switch (m.charAt(0)) {
-                                    // Character class
-                                    case "[":
-                                        // Escape or backreference
-                                    case "\\":
+                                    case "[": // Character class
+                                    case "\\":  // Escape or backreference
                                         if (currentToken["isGroup"] !== true) {
                                             currentToken = {
+                                                "isQuantifier": false,
                                                 "matches": [],
                                                 "isGroup": false
                                             };
@@ -2306,16 +2307,15 @@ Allows for using regular expressions as a mask
                                             currentToken["matches"].push(m);
                                         }
                                         break;
-                                        // Group opening
-                                    case "(":
+                                    case "(": // Group opening
                                         currentToken = {
+                                            "isQuantifier": false,
                                             "matches": [],
                                             "isGroup": true
                                         };
                                         opengroups.push(currentToken);
                                         break;
-                                        // Group closing
-                                    case ")":
+                                    case ")": // Group closing
                                         var groupToken = opengroups.pop();
                                         if (opengroups.length > 0) {
                                             opengroups[opengroups.length - 1]["matches"].push(groupToken);
@@ -2324,9 +2324,19 @@ Allows for using regular expressions as a mask
                                             opts.regexTokens.push(currentToken);
                                         }
                                         break;
-                                        // Not a character class, group opening/closing, escape sequence, or backreference
+                                    case "{": //Quantifier
+                                        var quantifier = {
+                                            "isQuantifier": true,
+                                            "matches": [m],
+                                            "isGroup": false
+                                        };
+                                        if (opengroups.length > 0) {
+                                            opengroups[opengroups.length - 1]["matches"].push(quantifier);
+                                        } else {
+                                            currentToken["matches"].push(quantifier);
+                                        }
+                                        break;
                                     default:
-                                        // Quantifier 
                                         // Vertical bar (alternator) 
                                         // ^ or $ anchor
                                         // Dot (.)
@@ -2350,9 +2360,20 @@ Allows for using regular expressions as a mask
                                 var matchToken = token["matches"][mndx];
                                 if (matchToken["isGroup"] == true) {
                                     isvalid = validateRegexToken(matchToken, true);
-                                } else {
+                                } else if (matchToken["isQuantifier"] == true) {
+                                    matchToken = matchToken["matches"][0];
+                                    var quantifierMax = opts.quantifierFilter.exec(matchToken)[0].replace("}", "");
+                                    var testExp = regexPart + "{1," + quantifierMax + "}"; //relax quantifier validation
+                                    for (var j = 0; j < openGroupCount; j++) {
+                                        testExp += ")";
+                                    }
+                                    var exp = new RegExp("^" + testExp + "$");
+                                    isvalid = exp.test(bufferStr);
+                                    regexPart += matchToken;
+                                }
+                                else {
                                     regexPart += matchToken;
-                                    var testExp = regexPart;
+                                    var testExp = regexPart.replace(/\|$/, "");
                                     for (var j = 0; j < openGroupCount; j++) {
                                         testExp += ")";
                                     }

File diff suppressed because it is too large
+ 66 - 65
dist/jquery.inputmask.bundle.min.js


File diff suppressed because it is too large
+ 1 - 1
dist/min/jquery.inputmask.js


File diff suppressed because it is too large
+ 4 - 3
dist/min/jquery.inputmask.regex.extensions.js


+ 1 - 1
jquery.inputmask.jquery.json

@@ -8,7 +8,7 @@
 		"inputmask",
 		"mask"
     ],
-    "version": "2.3.11",
+    "version": "2.3.12",
     "author": {
         "name": "Robin Herbots",
         "url": "http://github.com/RobinHerbots/jquery.inputmask"

+ 33 - 12
js/jquery.inputmask.regex.extensions.js

@@ -16,14 +16,16 @@ Allows for using regular expressions as a mask
             repeat: "*",
             regex: null,
             regexTokens: null,
+            //Thx to https://github.com/slevithan/regex-colorizer for the tokenizer regex
             tokenizer: /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g,
+            quantifierFilter: /[0-9]+[^,]/,
             definitions: {
                 'r': {
                     validator: function (chrs, buffer, pos, strict, opts) {
 
                         function analyseRegex() {
                             var currentToken = {
-                                "quantifier": undefined,
+                                "isQuantifier": false,
                                 "matches": [],
                                 "isGroup": false
                             }, match, m, opengroups = [];
@@ -34,12 +36,11 @@ Allows for using regular expressions as a mask
                             while (match = opts.tokenizer.exec(opts.regex)) {
                                 m = match[0];
                                 switch (m.charAt(0)) {
-                                    // Character class
-                                    case "[":
-                                        // Escape or backreference
-                                    case "\\":
+                                    case "[": // Character class
+                                    case "\\":  // Escape or backreference
                                         if (currentToken["isGroup"] !== true) {
                                             currentToken = {
+                                                "isQuantifier": false,
                                                 "matches": [],
                                                 "isGroup": false
                                             };
@@ -51,16 +52,15 @@ Allows for using regular expressions as a mask
                                             currentToken["matches"].push(m);
                                         }
                                         break;
-                                        // Group opening
-                                    case "(":
+                                    case "(": // Group opening
                                         currentToken = {
+                                            "isQuantifier": false,
                                             "matches": [],
                                             "isGroup": true
                                         };
                                         opengroups.push(currentToken);
                                         break;
-                                        // Group closing
-                                    case ")":
+                                    case ")": // Group closing
                                         var groupToken = opengroups.pop();
                                         if (opengroups.length > 0) {
                                             opengroups[opengroups.length - 1]["matches"].push(groupToken);
@@ -69,9 +69,19 @@ Allows for using regular expressions as a mask
                                             opts.regexTokens.push(currentToken);
                                         }
                                         break;
-                                        // Not a character class, group opening/closing, escape sequence, or backreference
+                                    case "{": //Quantifier
+                                        var quantifier = {
+                                            "isQuantifier": true,
+                                            "matches": [m],
+                                            "isGroup": false
+                                        };
+                                        if (opengroups.length > 0) {
+                                            opengroups[opengroups.length - 1]["matches"].push(quantifier);
+                                        } else {
+                                            currentToken["matches"].push(quantifier);
+                                        }
+                                        break;
                                     default:
-                                        // Quantifier 
                                         // Vertical bar (alternator) 
                                         // ^ or $ anchor
                                         // Dot (.)
@@ -95,7 +105,18 @@ Allows for using regular expressions as a mask
                                 var matchToken = token["matches"][mndx];
                                 if (matchToken["isGroup"] == true) {
                                     isvalid = validateRegexToken(matchToken, true);
-                                } else {
+                                } else if (matchToken["isQuantifier"] == true) {
+                                    matchToken = matchToken["matches"][0];
+                                    var quantifierMax = opts.quantifierFilter.exec(matchToken)[0].replace("}", "");
+                                    var testExp = regexPart + "{1," + quantifierMax + "}"; //relax quantifier validation
+                                    for (var j = 0; j < openGroupCount; j++) {
+                                        testExp += ")";
+                                    }
+                                    var exp = new RegExp("^" + testExp + "$");
+                                    isvalid = exp.test(bufferStr);
+                                    regexPart += matchToken;
+                                }
+                                else {
                                     regexPart += matchToken;
                                     var testExp = regexPart.replace(/\|$/, "");
                                     for (var j = 0; j < openGroupCount; j++) {

+ 46 - 0
qunit/tests.js

@@ -1070,4 +1070,50 @@ test("inputmask(\"Regex\", { regex: \"[a-zA-Z0-9._%-]+@[a-zA-Z0-9-]+\\.[a-zA-Z]{
     equal($("#testmask").val(), "some.body@mail.com", "Result " + $("#testmask").val());
 
     $("#testmask").remove();
+});
+
+test("inputmask(\"Regex\", { regex: \"(([2-9][0-9])-([0-9]{3}-[0-9]{3}))|((1|30|20|70)-([0-9]{3}-[0-9]{4}))\" - mrpanacs regex", function () {
+    $('body').append('<input type="text" id="testmask" />');
+    $("#testmask").inputmask("Regex", { regex: "(([2-9][0-9])-([0-9]{3}-[0-9]{3}))|((1|30|20|70)-([0-9]{3}-[0-9]{4}))" });
+
+    $("#testmask")[0].focus();
+    $("#testmask").Type("1-123-4562");
+
+    equal($("#testmask").val(), "1-123-4562", "Result " + $("#testmask").val());
+
+    $("#testmask").remove();
+});
+test("inputmask(\"Regex\", { regex: \"(([2-9][0-9])-([0-9]{3}-[0-9]{3}))|((1|30|20|70)-([0-9]{3}-[0-9]{4}))\" - mrpanacs regex", function () {
+    $('body').append('<input type="text" id="testmask" />');
+    $("#testmask").inputmask("Regex", { regex: "(([2-9][0-9])-([0-9]{3}-[0-9]{3}))|((1|30|20|70)-([0-9]{3}-[0-9]{4}))" });
+
+    $("#testmask")[0].focus();
+    $("#testmask").Type("20-222-2222");
+
+    equal($("#testmask").val(), "20-222-2222", "Result " + $("#testmask").val());
+
+    $("#testmask").remove();
+});
+test("inputmask(\"Regex\", { regex: \"(([2-9][0-9])-([0-9]{3}-[0-9]{3}))|((1|30|20|70)-([0-9]{3}-[0-9]{4}))\" - mrpanacs regex", function () {
+    $('body').append('<input type="text" id="testmask" />');
+    $("#testmask").inputmask("Regex", { regex: "(([2-9][0-9])-([0-9]{3}-[0-9]{3}))|((1|30|20|70)-([0-9]{3}-[0-9]{4}))" });
+
+    $("#testmask")[0].focus();
+    $("#testmask").Type("22-222-234");
+
+    equal($("#testmask").val(), "22-222-234", "Result " + $("#testmask").val());
+
+    $("#testmask").remove();
+});
+
+test("inputmask(\"Regex\", { regex: \"(([2-9][0-9])-([0-9]{3}-[0-9]{3}))|((1|30|20|70)-([0-9]{3}-[0-9]{4}))\" - mrpanacs regex", function () {
+    $('body').append('<input type="text" id="testmask" />');
+    $("#testmask").inputmask("Regex", { regex: "(([2-9][0-9])-([0-9]{3}-[0-9]{3}))|((1|30|20|70)-([0-9]{3}-[0-9]{4}))" });
+
+    $("#testmask")[0].focus();
+    $("#testmask").Type("70-12-34");
+
+    equal($("#testmask").val(), "70-123", "Result " + $("#testmask").val());
+
+    $("#testmask").remove();
 });