Browse Source

Character inserted via AltGraph or Ctrl+Alt ignores mask validation #192

Robin Herbots 11 years ago
parent
commit
7c4b87e435

+ 1 - 1
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "jquery.inputmask",
-  "version": "3.0.64",
+  "version": "3.0.65",
   "main": [
     "./dist/inputmask/jquery.inputmask.js",
     "./dist/inputmask/jquery.inputmask.extensions.js",

+ 1 - 1
build.properties

@@ -7,7 +7,7 @@ distdir = dist
 
 build.major = 3
 build.minor = 0
-build.revision = 64
+build.revision = 65
 
 target = jquery.inputmask.bundle.js
 target.min = jquery.inputmask.bundle.min.js

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


+ 9 - 7
dist/jquery.inputmask.bundle.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2014 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 3.0.64
+* Version: 3.0.65
 */
 
 (function (factory) {
@@ -1385,7 +1385,9 @@
                 setTimeout(function () {
                     caret(that, caret(that).begin - 1);
                     var keypress = $.Event("keypress");
-                    keypress.which = e.originalEvent.data.charCodeAt(0);
+                    keypress.which = e.originalEvent.data.charCodeAt(0);
+                    skipKeyPressEvent = false;
+                     ignorable = false;
                     keypressEvent.call(that, keypress, undefined, undefined, false);
                     var forwardPosition = getMaskSet()["p"];
                     writeBuffer(that, getBuffer(), opts.numericInput ? seekPrevious(forwardPosition) : forwardPosition);
@@ -1861,7 +1863,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2014 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 3.0.64
+Version: 3.0.65
 
 Optional extensions on the jquery.inputmask base
 */
@@ -1988,7 +1990,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2014 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 3.0.64
+Version: 3.0.65
 
 Optional extensions on the jquery.inputmask base
 */
@@ -2482,7 +2484,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2014 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 3.0.64
+Version: 3.0.65
 
 Optional extensions on the jquery.inputmask base
 */
@@ -2741,7 +2743,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2014 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 3.0.64
+Version: 3.0.65
 
 Regex extensions on the jquery.inputmask base
 Allows for using regular expressions as a mask
@@ -2934,7 +2936,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2014 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 3.0.64
+Version: 3.0.65
 
 Phone extension.
 When using this extension make sure you specify the correct url to get the masks

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


+ 1 - 1
jquery.inputmask.jquery.json

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

+ 494 - 494
js/jquery.inputmask.date.extensions.js

@@ -1,494 +1,494 @@
-/*
-Input Mask plugin extensions
-http://github.com/RobinHerbots/jquery.inputmask
-Copyright (c) 2010 - 2014 Robin Herbots
-Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 0.0.0
-
-Optional extensions on the jquery.inputmask base
-*/
-(function (factory) {
-    if (typeof define === 'function' && define.amd) {
-        define(['jquery', './jquery.inputmask'], factory);
-    } else {
-        factory(jQuery);
-    }
-}(function ($) {
-    //date & time aliases
-    $.extend($.inputmask.defaults.definitions, {
-        'h': { //hours
-            validator: "[01][0-9]|2[0-3]",
-            cardinality: 2,
-            prevalidator: [{ validator: "[0-2]", cardinality: 1 }]
-        },
-        's': { //seconds || minutes
-            validator: "[0-5][0-9]",
-            cardinality: 2,
-            prevalidator: [{ validator: "[0-5]", cardinality: 1 }]
-        },
-        'd': { //basic day
-            validator: "0[1-9]|[12][0-9]|3[01]",
-            cardinality: 2,
-            prevalidator: [{ validator: "[0-3]", cardinality: 1 }]
-        },
-        'm': { //basic month
-            validator: "0[1-9]|1[012]",
-            cardinality: 2,
-            prevalidator: [{ validator: "[01]", cardinality: 1 }]
-        },
-        'y': { //basic year
-            validator: "(19|20)\\d{2}",
-            cardinality: 4,
-            prevalidator: [
-                        { validator: "[12]", cardinality: 1 },
-                        { validator: "(19|20)", cardinality: 2 },
-                        { validator: "(19|20)\\d", cardinality: 3 }
-            ]
-        }
-    });
-    $.extend($.inputmask.defaults.aliases, {
-        'dd/mm/yyyy': {
-            mask: "1/2/y",
-            placeholder: "dd/mm/yyyy",
-            regex: {
-                val1pre: new RegExp("[0-3]"), //daypre
-                val1: new RegExp("0[1-9]|[12][0-9]|3[01]"), //day
-                val2pre: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[1-9]|[12][0-9]|3[01])" + escapedSeparator + "[01])"); }, //monthpre
-                val2: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[1-9]|[12][0-9])" + escapedSeparator + "(0[1-9]|1[012]))|(30" + escapedSeparator + "(0[13-9]|1[012]))|(31" + escapedSeparator + "(0[13578]|1[02]))"); }//month
-            },
-            leapday: "29/02/",
-            separator: '/',
-            yearrange: { minyear: 1900, maxyear: 2099 },
-            isInYearRange: function (chrs, minyear, maxyear) {
-                if (isNaN(chrs)) return false;
-                var enteredyear = parseInt(chrs.concat(minyear.toString().slice(chrs.length)));
-                var enteredyear2 = parseInt(chrs.concat(maxyear.toString().slice(chrs.length)));
-                return (!isNaN(enteredyear) ? minyear <= enteredyear && enteredyear <= maxyear : false) ||
-            		   (!isNaN(enteredyear2) ? minyear <= enteredyear2 && enteredyear2 <= maxyear : false);
-            },
-            determinebaseyear: function (minyear, maxyear, hint) {
-                var currentyear = (new Date()).getFullYear();
-                if (minyear > currentyear) return minyear;
-                if (maxyear < currentyear) {
-                    var maxYearPrefix = maxyear.toString().slice(0, 2);
-                    var maxYearPostfix = maxyear.toString().slice(2, 4);
-                    while (maxyear < maxYearPrefix + hint) {
-                        maxYearPrefix--;
-                    }
-                    var maxxYear = maxYearPrefix + maxYearPostfix;
-                    return minyear > maxxYear ? minyear : maxxYear;
-                }
-
-                return currentyear;
-            },
-            onKeyUp: function (e, buffer, caretPos, opts) {
-                var $input = $(this);
-                if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {
-                    var today = new Date();
-                    $input.val(today.getDate().toString() + (today.getMonth() + 1).toString() + today.getFullYear().toString());
-                }
-            },
-            definitions: {
-                '1': { //val1 ~ day or month
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        var isValid = opts.regex.val1.test(chrs);
-                        if (!strict && !isValid) {
-                            if (chrs.charAt(1) == opts.separator || "-./".indexOf(chrs.charAt(1)) != -1) {
-                                isValid = opts.regex.val1.test("0" + chrs.charAt(0));
-                                if (isValid) {
-                                    maskset.buffer[pos - 1] = "0";
-                                    return { "refreshFromBuffer": { start: pos - 1, end: pos }, "pos": pos, "c": chrs.charAt(0) };
-                                }
-                            }
-                        }
-                        return isValid;
-                    },
-                    cardinality: 2,
-                    prevalidator: [{
-                        validator: function (chrs, maskset, pos, strict, opts) {
-                            if (!isNaN(maskset.buffer[pos + 1])) chrs += maskset.buffer[pos + 1];
-                            var isValid = chrs.length == 1 ? opts.regex.val1pre.test(chrs) : opts.regex.val1.test(chrs);
-                            if (!strict && !isValid) {
-                                isValid = opts.regex.val1.test("0" + chrs);
-                                if (isValid) {
-                                    maskset.buffer[pos] = "0";
-                                    pos++;
-                                    return { "pos": pos };
-                                }
-                            }
-                            return isValid;
-                        }, cardinality: 1
-                    }]
-                },
-                '2': { //val2 ~ day or month
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        var frontValue = (opts.mask.indexOf("2") == opts.mask.length - 1) ? maskset.buffer.join('').substr(5, 3) : maskset.buffer.join('').substr(0, 3);
-                        if (frontValue.indexOf(opts.placeholder[0]) != -1) frontValue = "01" + opts.separator;
-                        var isValid = opts.regex.val2(opts.separator).test(frontValue + chrs);
-                        if (!strict && !isValid) {
-                            if (chrs.charAt(1) == opts.separator || "-./".indexOf(chrs.charAt(1)) != -1) {
-                                isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs.charAt(0));
-                                if (isValid) {
-                                    maskset.buffer[pos - 1] = "0";
-                                    return { "refreshFromBuffer": { start: pos - 1, end: pos }, "pos": pos, "c": chrs.charAt(0) };
-                                }
-                            }
-                        }
-
-                        //check leap yeap
-                        if ((opts.mask.indexOf("2") == opts.mask.length - 1) && isValid) {
-                            var dayMonthValue = maskset.buffer.join('').substr(4, 4) + chrs;
-                            if (dayMonthValue != opts.leapday)
-                                return true;
-                            else {
-                                var year = parseInt(maskset.buffer.join('').substr(0, 4), 10);  //detect leap year
-                                if (year % 4 === 0)
-                                    if (year % 100 === 0)
-                                        if (year % 400 === 0)
-                                            return true;
-                                        else return false;
-                                    else return true;
-                                else return false;
-                            }
-                        }
-
-                        return isValid;
-                    },
-                    cardinality: 2,
-                    prevalidator: [{
-                        validator: function (chrs, maskset, pos, strict, opts) {
-                            if (!isNaN(maskset.buffer[pos + 1])) chrs += maskset.buffer[pos + 1];
-                            var frontValue = (opts.mask.indexOf("2") == opts.mask.length - 1) ? maskset.buffer.join('').substr(5, 3) : maskset.buffer.join('').substr(0, 3);
-                            if (frontValue.indexOf(opts.placeholder[0]) != -1) frontValue = "01" + opts.separator;
-                            var isValid = chrs.length == 1 ? opts.regex.val2pre(opts.separator).test(frontValue + chrs) : opts.regex.val2(opts.separator).test(frontValue + chrs);
-                            if (!strict && !isValid) {
-                                isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs);
-                                if (isValid) {
-                                    maskset.buffer[pos] = "0";
-                                    pos++;
-                                    return { "pos": pos };
-                                }
-                            }
-                            return isValid;
-                        }, cardinality: 1
-                    }]
-                },
-                'y': { //year
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        if (opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) {
-                            var dayMonthValue = maskset.buffer.join('').substr(0, 6);
-                            if (dayMonthValue != opts.leapday)
-                                return true;
-                            else {
-                                var year = parseInt(chrs, 10);//detect leap year
-                                if (year % 4 === 0)
-                                    if (year % 100 === 0)
-                                        if (year % 400 === 0)
-                                            return true;
-                                        else return false;
-                                    else return true;
-                                else return false;
-                            }
-                        } else return false;
-                    },
-                    cardinality: 4,
-                    prevalidator: [
-                {
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
-                        if (!strict && !isValid) {
-                            var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 1);
-
-                            isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
-                            if (isValid) {
-                                maskset.buffer[pos++] = yearPrefix.charAt(0);
-                                return { "pos": pos };
-                            }
-                            yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 2);
-
-                            isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
-                            if (isValid) {
-                                maskset.buffer[pos++] = yearPrefix.charAt(0);
-                                maskset.buffer[pos++] = yearPrefix.charAt(1);
-                                return { "pos": pos };
-                            }
-                        }
-                        return isValid;
-                    },
-                    cardinality: 1
-                },
-                {
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
-                        if (!strict && !isValid) {
-                            var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2);
-
-                            isValid = opts.isInYearRange(chrs[0] + yearPrefix[1] + chrs[1], opts.yearrange.minyear, opts.yearrange.maxyear);
-                            if (isValid) {
-                                maskset.buffer[pos++] = yearPrefix.charAt(1);
-                                return { "pos": pos };
-                            }
-
-                            yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2);
-                            if (opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) {
-                                var dayMonthValue = maskset.buffer.join('').substr(0, 6);
-                                if (dayMonthValue != opts.leapday)
-                                    isValid = true;
-                                else {
-                                    var year = parseInt(chrs, 10);//detect leap year
-                                    if (year % 4 === 0)
-                                        if (year % 100 === 0)
-                                            if (year % 400 === 0)
-                                                isValid = true;
-                                            else isValid = false;
-                                        else isValid = true;
-                                    else isValid = false;
-                                }
-                            } else isValid = false;
-                            if (isValid) {
-                                maskset.buffer[pos - 1] = yearPrefix.charAt(0);
-                                maskset.buffer[pos++] = yearPrefix.charAt(1);
-                                maskset.buffer[pos++] = chrs.charAt(0);
-                                return { "refreshFromBuffer": { start: pos - 3, end: pos }, "pos": pos };
-                            }
-                        }
-                        return isValid;
-                    }, cardinality: 2
-                },
-                {
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        return opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
-                    }, cardinality: 3
-                }
-                    ]
-                }
-            },
-            insertMode: false,
-            autoUnmask: false
-        },
-        'mm/dd/yyyy': {
-            placeholder: "mm/dd/yyyy",
-            alias: "dd/mm/yyyy", //reuse functionality of dd/mm/yyyy alias
-            regex: {
-                val2pre: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[13-9]|1[012])" + escapedSeparator + "[0-3])|(02" + escapedSeparator + "[0-2])"); }, //daypre
-                val2: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "(0[1-9]|[12][0-9]))|((0[13-9]|1[012])" + escapedSeparator + "30)|((0[13578]|1[02])" + escapedSeparator + "31)"); }, //day
-                val1pre: new RegExp("[01]"), //monthpre
-                val1: new RegExp("0[1-9]|1[012]") //month
-            },
-            leapday: "02/29/",
-            onKeyUp: function (e, buffer, caretPos, opts) {
-                var $input = $(this);
-                if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {
-                    var today = new Date();
-                    $input.val((today.getMonth() + 1).toString() + today.getDate().toString() + today.getFullYear().toString());
-                }
-            }
-        },
-        'yyyy/mm/dd': {
-            mask: "y/1/2",
-            placeholder: "yyyy/mm/dd",
-            alias: "mm/dd/yyyy",
-            leapday: "/02/29",
-            onKeyUp: function (e, buffer, caretPos, opts) {
-                var $input = $(this);
-                if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {
-                    var today = new Date();
-                    $input.val(today.getFullYear().toString() + (today.getMonth() + 1).toString() + today.getDate().toString());
-                }
-            }
-        },
-        'dd.mm.yyyy': {
-            mask: "1.2.y",
-            placeholder: "dd.mm.yyyy",
-            leapday: "29.02.",
-            separator: '.',
-            alias: "dd/mm/yyyy"
-        },
-        'dd-mm-yyyy': {
-            mask: "1-2-y",
-            placeholder: "dd-mm-yyyy",
-            leapday: "29-02-",
-            separator: '-',
-            alias: "dd/mm/yyyy"
-        },
-        'mm.dd.yyyy': {
-            mask: "1.2.y",
-            placeholder: "mm.dd.yyyy",
-            leapday: "02.29.",
-            separator: '.',
-            alias: "mm/dd/yyyy"
-        },
-        'mm-dd-yyyy': {
-            mask: "1-2-y",
-            placeholder: "mm-dd-yyyy",
-            leapday: "02-29-",
-            separator: '-',
-            alias: "mm/dd/yyyy"
-        },
-        'yyyy.mm.dd': {
-            mask: "y.1.2",
-            placeholder: "yyyy.mm.dd",
-            leapday: ".02.29",
-            separator: '.',
-            alias: "yyyy/mm/dd"
-        },
-        'yyyy-mm-dd': {
-            mask: "y-1-2",
-            placeholder: "yyyy-mm-dd",
-            leapday: "-02-29",
-            separator: '-',
-            alias: "yyyy/mm/dd"
-        },
-        'datetime': {
-            mask: "1/2/y h:s",
-            placeholder: "dd/mm/yyyy hh:mm",
-            alias: "dd/mm/yyyy",
-            regex: {
-                hrspre: new RegExp("[012]"), //hours pre
-                hrs24: new RegExp("2[0-4]|1[3-9]"),
-                hrs: new RegExp("[01][0-9]|2[0-4]"), //hours
-                ampm: new RegExp("^[a|p|A|P][m|M]"),
-                mspre: new RegExp("[0-5]"), //minutes/seconds pre
-                ms: new RegExp("[0-5][0-9]")
-            },
-            timeseparator: ':',
-            hourFormat: "24", // or 12
-            definitions: {
-                'h': { //hours
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        if (opts.hourFormat == "24") {
-                            if (parseInt(chrs, 10) == 24) {
-                                maskset.buffer[pos - 1] = "0";
-                                maskset.buffer[pos] = "0";
-                                return { "refreshFromBuffer": { start: pos - 1, end: pos }, "c": "0" };
-                            }
-                        }
-
-                        var isValid = opts.regex.hrs.test(chrs);
-                        if (!strict && !isValid) {
-                            if (chrs.charAt(1) == opts.timeseparator || "-.:".indexOf(chrs.charAt(1)) != -1) {
-                                isValid = opts.regex.hrs.test("0" + chrs.charAt(0));
-                                if (isValid) {
-                                    maskset.buffer[pos - 1] = "0";
-                                    maskset.buffer[pos] = chrs.charAt(0);
-                                    pos++;
-                                    return { "refreshFromBuffer": { start: pos - 2, end: pos }, "pos": pos, "c": opts.timeseparator };
-                                }
-                            }
-                        }
-
-                        if (isValid && opts.hourFormat !== "24" && opts.regex.hrs24.test(chrs)) {
-
-                            var tmp = parseInt(chrs, 10);
-
-                            if (tmp == 24) {
-                                maskset.buffer[pos + 5] = "a";
-                                maskset.buffer[pos + 6] = "m";
-                            } else {
-                                maskset.buffer[pos + 5] = "p";
-                                maskset.buffer[pos + 6] = "m";
-                            }
-
-                            tmp = tmp - 12;
-
-                            if (tmp < 10) {
-                                maskset.buffer[pos] = tmp.toString();
-                                maskset.buffer[pos - 1] = "0";
-                            } else {
-                                maskset.buffer[pos] = tmp.toString().charAt(1);
-                                maskset.buffer[pos - 1] = tmp.toString().charAt(0);
-                            }
-
-                            return { "refreshFromBuffer": { start: pos - 1, end: pos + 6 }, "c": maskset.buffer[pos] };
-                        }
-
-                        return isValid;
-                    },
-                    cardinality: 2,
-                    prevalidator: [{
-                        validator: function (chrs, maskset, pos, strict, opts) {
-                            var isValid = opts.regex.hrspre.test(chrs);
-                            if (!strict && !isValid) {
-                                isValid = opts.regex.hrs.test("0" + chrs);
-                                if (isValid) {
-                                    maskset.buffer[pos] = "0";
-                                    pos++;
-                                    return { "pos": pos };
-                                }
-                            }
-                            return isValid;
-                        }, cardinality: 1
-                    }]
-                },
-                's': { //seconds || minutes
-                    validator: "[0-5][0-9]",
-                    cardinality: 2,
-                    prevalidator: [
-                        {
-                            validator: function (chrs, maskset, pos, strict, opts) {
-                                var isValid = opts.regex.mspre.test(chrs);
-                                if (!strict && !isValid) {
-                                    isValid = opts.regex.ms.test("0" + chrs);
-                                    if (isValid) {
-                                        maskset.buffer[pos] = "0";
-                                        pos++;
-                                        return { "pos": pos };
-                                    }
-                                }
-                                return isValid;
-                            }, cardinality: 1
-                        }]
-                },
-                't': { //am/pm
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        return opts.regex.ampm.test(chrs + "m");
-                    },
-                    casing: "lower",
-                    cardinality: 1
-                }
-            },
-            insertMode: false,
-            autoUnmask: false
-        },
-        'datetime12': {
-            mask: "1/2/y h:s t\\m",
-            placeholder: "dd/mm/yyyy hh:mm xm",
-            alias: "datetime",
-            hourFormat: "12"
-        },
-        'hh:mm t': {
-            mask: "h:s t\\m",
-            placeholder: "hh:mm xm",
-            alias: "datetime",
-            hourFormat: "12"
-        },
-        'h:s t': {
-            mask: "h:s t\\m",
-            placeholder: "hh:mm xm",
-            alias: "datetime",
-            hourFormat: "12"
-        },
-        'hh:mm:ss': {
-            mask: "h:s:s",
-            placeholder: "hh:mm:ss",
-            alias: "datetime",
-            autoUnmask: false
-        },
-        'hh:mm': {
-            mask: "h:s",
-            placeholder: "hh:mm",
-            alias: "datetime",
-            autoUnmask: false
-        },
-        'date': {
-            alias: "dd/mm/yyyy" // "mm/dd/yyyy"
-        },
-        'mm/yyyy': {
-            mask: "1/y",
-            placeholder: "mm/yyyy",
-            leapday: "donotuse",
-            separator: '/',
-            alias: "mm/dd/yyyy"
-        }
-    });
-}));
+/*
+Input Mask plugin extensions
+http://github.com/RobinHerbots/jquery.inputmask
+Copyright (c) 2010 - 2014 Robin Herbots
+Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
+Version: 0.0.0
+
+Optional extensions on the jquery.inputmask base
+*/
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery', './jquery.inputmask'], factory);
+    } else {
+        factory(jQuery);
+    }
+}(function ($) {
+    //date & time aliases
+    $.extend($.inputmask.defaults.definitions, {
+        'h': { //hours
+            validator: "[01][0-9]|2[0-3]",
+            cardinality: 2,
+            prevalidator: [{ validator: "[0-2]", cardinality: 1 }]
+        },
+        's': { //seconds || minutes
+            validator: "[0-5][0-9]",
+            cardinality: 2,
+            prevalidator: [{ validator: "[0-5]", cardinality: 1 }]
+        },
+        'd': { //basic day
+            validator: "0[1-9]|[12][0-9]|3[01]",
+            cardinality: 2,
+            prevalidator: [{ validator: "[0-3]", cardinality: 1 }]
+        },
+        'm': { //basic month
+            validator: "0[1-9]|1[012]",
+            cardinality: 2,
+            prevalidator: [{ validator: "[01]", cardinality: 1 }]
+        },
+        'y': { //basic year
+            validator: "(19|20)\\d{2}",
+            cardinality: 4,
+            prevalidator: [
+                        { validator: "[12]", cardinality: 1 },
+                        { validator: "(19|20)", cardinality: 2 },
+                        { validator: "(19|20)\\d", cardinality: 3 }
+            ]
+        }
+    });
+    $.extend($.inputmask.defaults.aliases, {
+        'dd/mm/yyyy': {
+            mask: "1/2/y",
+            placeholder: "dd/mm/yyyy",
+            regex: {
+                val1pre: new RegExp("[0-3]"), //daypre
+                val1: new RegExp("0[1-9]|[12][0-9]|3[01]"), //day
+                val2pre: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[1-9]|[12][0-9]|3[01])" + escapedSeparator + "[01])"); }, //monthpre
+                val2: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[1-9]|[12][0-9])" + escapedSeparator + "(0[1-9]|1[012]))|(30" + escapedSeparator + "(0[13-9]|1[012]))|(31" + escapedSeparator + "(0[13578]|1[02]))"); }//month
+            },
+            leapday: "29/02/",
+            separator: '/',
+            yearrange: { minyear: 1900, maxyear: 2099 },
+            isInYearRange: function (chrs, minyear, maxyear) {
+                if (isNaN(chrs)) return false;
+                var enteredyear = parseInt(chrs.concat(minyear.toString().slice(chrs.length)));
+                var enteredyear2 = parseInt(chrs.concat(maxyear.toString().slice(chrs.length)));
+                return (!isNaN(enteredyear) ? minyear <= enteredyear && enteredyear <= maxyear : false) ||
+            		   (!isNaN(enteredyear2) ? minyear <= enteredyear2 && enteredyear2 <= maxyear : false);
+            },
+            determinebaseyear: function (minyear, maxyear, hint) {
+                var currentyear = (new Date()).getFullYear();
+                if (minyear > currentyear) return minyear;
+                if (maxyear < currentyear) {
+                    var maxYearPrefix = maxyear.toString().slice(0, 2);
+                    var maxYearPostfix = maxyear.toString().slice(2, 4);
+                    while (maxyear < maxYearPrefix + hint) {
+                        maxYearPrefix--;
+                    }
+                    var maxxYear = maxYearPrefix + maxYearPostfix;
+                    return minyear > maxxYear ? minyear : maxxYear;
+                }
+
+                return currentyear;
+            },
+            onKeyUp: function (e, buffer, caretPos, opts) {
+                var $input = $(this);
+                if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {
+                    var today = new Date();
+                    $input.val(today.getDate().toString() + (today.getMonth() + 1).toString() + today.getFullYear().toString());
+                }
+            },
+            definitions: {
+                '1': { //val1 ~ day or month
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        var isValid = opts.regex.val1.test(chrs);
+                        if (!strict && !isValid) {
+                            if (chrs.charAt(1) == opts.separator || "-./".indexOf(chrs.charAt(1)) != -1) {
+                                isValid = opts.regex.val1.test("0" + chrs.charAt(0));
+                                if (isValid) {
+                                    maskset.buffer[pos - 1] = "0";
+                                    return { "refreshFromBuffer": { start: pos - 1, end: pos }, "pos": pos, "c": chrs.charAt(0) };
+                                }
+                            }
+                        }
+                        return isValid;
+                    },
+                    cardinality: 2,
+                    prevalidator: [{
+                        validator: function (chrs, maskset, pos, strict, opts) {
+                            if (!isNaN(maskset.buffer[pos + 1])) chrs += maskset.buffer[pos + 1];
+                            var isValid = chrs.length == 1 ? opts.regex.val1pre.test(chrs) : opts.regex.val1.test(chrs);
+                            if (!strict && !isValid) {
+                                isValid = opts.regex.val1.test("0" + chrs);
+                                if (isValid) {
+                                    maskset.buffer[pos] = "0";
+                                    pos++;
+                                    return { "pos": pos };
+                                }
+                            }
+                            return isValid;
+                        }, cardinality: 1
+                    }]
+                },
+                '2': { //val2 ~ day or month
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        var frontValue = (opts.mask.indexOf("2") == opts.mask.length - 1) ? maskset.buffer.join('').substr(5, 3) : maskset.buffer.join('').substr(0, 3);
+                        if (frontValue.indexOf(opts.placeholder[0]) != -1) frontValue = "01" + opts.separator;
+                        var isValid = opts.regex.val2(opts.separator).test(frontValue + chrs);
+                        if (!strict && !isValid) {
+                            if (chrs.charAt(1) == opts.separator || "-./".indexOf(chrs.charAt(1)) != -1) {
+                                isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs.charAt(0));
+                                if (isValid) {
+                                    maskset.buffer[pos - 1] = "0";
+                                    return { "refreshFromBuffer": { start: pos - 1, end: pos }, "pos": pos, "c": chrs.charAt(0) };
+                                }
+                            }
+                        }
+
+                        //check leap yeap
+                        if ((opts.mask.indexOf("2") == opts.mask.length - 1) && isValid) {
+                            var dayMonthValue = maskset.buffer.join('').substr(4, 4) + chrs;
+                            if (dayMonthValue != opts.leapday)
+                                return true;
+                            else {
+                                var year = parseInt(maskset.buffer.join('').substr(0, 4), 10);  //detect leap year
+                                if (year % 4 === 0)
+                                    if (year % 100 === 0)
+                                        if (year % 400 === 0)
+                                            return true;
+                                        else return false;
+                                    else return true;
+                                else return false;
+                            }
+                        }
+
+                        return isValid;
+                    },
+                    cardinality: 2,
+                    prevalidator: [{
+                        validator: function (chrs, maskset, pos, strict, opts) {
+                            if (!isNaN(maskset.buffer[pos + 1])) chrs += maskset.buffer[pos + 1];
+                            var frontValue = (opts.mask.indexOf("2") == opts.mask.length - 1) ? maskset.buffer.join('').substr(5, 3) : maskset.buffer.join('').substr(0, 3);
+                            if (frontValue.indexOf(opts.placeholder[0]) != -1) frontValue = "01" + opts.separator;
+                            var isValid = chrs.length == 1 ? opts.regex.val2pre(opts.separator).test(frontValue + chrs) : opts.regex.val2(opts.separator).test(frontValue + chrs);
+                            if (!strict && !isValid) {
+                                isValid = opts.regex.val2(opts.separator).test(frontValue + "0" + chrs);
+                                if (isValid) {
+                                    maskset.buffer[pos] = "0";
+                                    pos++;
+                                    return { "pos": pos };
+                                }
+                            }
+                            return isValid;
+                        }, cardinality: 1
+                    }]
+                },
+                'y': { //year
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        if (opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) {
+                            var dayMonthValue = maskset.buffer.join('').substr(0, 6);
+                            if (dayMonthValue != opts.leapday)
+                                return true;
+                            else {
+                                var year = parseInt(chrs, 10);//detect leap year
+                                if (year % 4 === 0)
+                                    if (year % 100 === 0)
+                                        if (year % 400 === 0)
+                                            return true;
+                                        else return false;
+                                    else return true;
+                                else return false;
+                            }
+                        } else return false;
+                    },
+                    cardinality: 4,
+                    prevalidator: [
+                {
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
+                        if (!strict && !isValid) {
+                            var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 1);
+
+                            isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
+                            if (isValid) {
+                                maskset.buffer[pos++] = yearPrefix.charAt(0);
+                                return { "pos": pos };
+                            }
+                            yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + "0").toString().slice(0, 2);
+
+                            isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
+                            if (isValid) {
+                                maskset.buffer[pos++] = yearPrefix.charAt(0);
+                                maskset.buffer[pos++] = yearPrefix.charAt(1);
+                                return { "pos": pos };
+                            }
+                        }
+                        return isValid;
+                    },
+                    cardinality: 1
+                },
+                {
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
+                        if (!strict && !isValid) {
+                            var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2);
+
+                            isValid = opts.isInYearRange(chrs[0] + yearPrefix[1] + chrs[1], opts.yearrange.minyear, opts.yearrange.maxyear);
+                            if (isValid) {
+                                maskset.buffer[pos++] = yearPrefix.charAt(1);
+                                return { "pos": pos };
+                            }
+
+                            yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2);
+                            if (opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) {
+                                var dayMonthValue = maskset.buffer.join('').substr(0, 6);
+                                if (dayMonthValue != opts.leapday)
+                                    isValid = true;
+                                else {
+                                    var year = parseInt(chrs, 10);//detect leap year
+                                    if (year % 4 === 0)
+                                        if (year % 100 === 0)
+                                            if (year % 400 === 0)
+                                                isValid = true;
+                                            else isValid = false;
+                                        else isValid = true;
+                                    else isValid = false;
+                                }
+                            } else isValid = false;
+                            if (isValid) {
+                                maskset.buffer[pos - 1] = yearPrefix.charAt(0);
+                                maskset.buffer[pos++] = yearPrefix.charAt(1);
+                                maskset.buffer[pos++] = chrs.charAt(0);
+                                return { "refreshFromBuffer": { start: pos - 3, end: pos }, "pos": pos };
+                            }
+                        }
+                        return isValid;
+                    }, cardinality: 2
+                },
+                {
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        return opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);
+                    }, cardinality: 3
+                }
+                    ]
+                }
+            },
+            insertMode: false,
+            autoUnmask: false
+        },
+        'mm/dd/yyyy': {
+            placeholder: "mm/dd/yyyy",
+            alias: "dd/mm/yyyy", //reuse functionality of dd/mm/yyyy alias
+            regex: {
+                val2pre: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[13-9]|1[012])" + escapedSeparator + "[0-3])|(02" + escapedSeparator + "[0-2])"); }, //daypre
+                val2: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp("((0[1-9]|1[012])" + escapedSeparator + "(0[1-9]|[12][0-9]))|((0[13-9]|1[012])" + escapedSeparator + "30)|((0[13578]|1[02])" + escapedSeparator + "31)"); }, //day
+                val1pre: new RegExp("[01]"), //monthpre
+                val1: new RegExp("0[1-9]|1[012]") //month
+            },
+            leapday: "02/29/",
+            onKeyUp: function (e, buffer, caretPos, opts) {
+                var $input = $(this);
+                if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {
+                    var today = new Date();
+                    $input.val((today.getMonth() + 1).toString() + today.getDate().toString() + today.getFullYear().toString());
+                }
+            }
+        },
+        'yyyy/mm/dd': {
+            mask: "y/1/2",
+            placeholder: "yyyy/mm/dd",
+            alias: "mm/dd/yyyy",
+            leapday: "/02/29",
+            onKeyUp: function (e, buffer, caretPos, opts) {
+                var $input = $(this);
+                if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {
+                    var today = new Date();
+                    $input.val(today.getFullYear().toString() + (today.getMonth() + 1).toString() + today.getDate().toString());
+                }
+            }
+        },
+        'dd.mm.yyyy': {
+            mask: "1.2.y",
+            placeholder: "dd.mm.yyyy",
+            leapday: "29.02.",
+            separator: '.',
+            alias: "dd/mm/yyyy"
+        },
+        'dd-mm-yyyy': {
+            mask: "1-2-y",
+            placeholder: "dd-mm-yyyy",
+            leapday: "29-02-",
+            separator: '-',
+            alias: "dd/mm/yyyy"
+        },
+        'mm.dd.yyyy': {
+            mask: "1.2.y",
+            placeholder: "mm.dd.yyyy",
+            leapday: "02.29.",
+            separator: '.',
+            alias: "mm/dd/yyyy"
+        },
+        'mm-dd-yyyy': {
+            mask: "1-2-y",
+            placeholder: "mm-dd-yyyy",
+            leapday: "02-29-",
+            separator: '-',
+            alias: "mm/dd/yyyy"
+        },
+        'yyyy.mm.dd': {
+            mask: "y.1.2",
+            placeholder: "yyyy.mm.dd",
+            leapday: ".02.29",
+            separator: '.',
+            alias: "yyyy/mm/dd"
+        },
+        'yyyy-mm-dd': {
+            mask: "y-1-2",
+            placeholder: "yyyy-mm-dd",
+            leapday: "-02-29",
+            separator: '-',
+            alias: "yyyy/mm/dd"
+        },
+        'datetime': {
+            mask: "1/2/y h:s",
+            placeholder: "dd/mm/yyyy hh:mm",
+            alias: "dd/mm/yyyy",
+            regex: {
+                hrspre: new RegExp("[012]"), //hours pre
+                hrs24: new RegExp("2[0-4]|1[3-9]"),
+                hrs: new RegExp("[01][0-9]|2[0-4]"), //hours
+                ampm: new RegExp("^[a|p|A|P][m|M]"),
+                mspre: new RegExp("[0-5]"), //minutes/seconds pre
+                ms: new RegExp("[0-5][0-9]")
+            },
+            timeseparator: ':',
+            hourFormat: "24", // or 12
+            definitions: {
+                'h': { //hours
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        if (opts.hourFormat == "24") {
+                            if (parseInt(chrs, 10) == 24) {
+                                maskset.buffer[pos - 1] = "0";
+                                maskset.buffer[pos] = "0";
+                                return { "refreshFromBuffer": { start: pos - 1, end: pos }, "c": "0" };
+                            }
+                        }
+
+                        var isValid = opts.regex.hrs.test(chrs);
+                        if (!strict && !isValid) {
+                            if (chrs.charAt(1) == opts.timeseparator || "-.:".indexOf(chrs.charAt(1)) != -1) {
+                                isValid = opts.regex.hrs.test("0" + chrs.charAt(0));
+                                if (isValid) {
+                                    maskset.buffer[pos - 1] = "0";
+                                    maskset.buffer[pos] = chrs.charAt(0);
+                                    pos++;
+                                    return { "refreshFromBuffer": { start: pos - 2, end: pos }, "pos": pos, "c": opts.timeseparator };
+                                }
+                            }
+                        }
+
+                        if (isValid && opts.hourFormat !== "24" && opts.regex.hrs24.test(chrs)) {
+
+                            var tmp = parseInt(chrs, 10);
+
+                            if (tmp == 24) {
+                                maskset.buffer[pos + 5] = "a";
+                                maskset.buffer[pos + 6] = "m";
+                            } else {
+                                maskset.buffer[pos + 5] = "p";
+                                maskset.buffer[pos + 6] = "m";
+                            }
+
+                            tmp = tmp - 12;
+
+                            if (tmp < 10) {
+                                maskset.buffer[pos] = tmp.toString();
+                                maskset.buffer[pos - 1] = "0";
+                            } else {
+                                maskset.buffer[pos] = tmp.toString().charAt(1);
+                                maskset.buffer[pos - 1] = tmp.toString().charAt(0);
+                            }
+
+                            return { "refreshFromBuffer": { start: pos - 1, end: pos + 6 }, "c": maskset.buffer[pos] };
+                        }
+
+                        return isValid;
+                    },
+                    cardinality: 2,
+                    prevalidator: [{
+                        validator: function (chrs, maskset, pos, strict, opts) {
+                            var isValid = opts.regex.hrspre.test(chrs);
+                            if (!strict && !isValid) {
+                                isValid = opts.regex.hrs.test("0" + chrs);
+                                if (isValid) {
+                                    maskset.buffer[pos] = "0";
+                                    pos++;
+                                    return { "pos": pos };
+                                }
+                            }
+                            return isValid;
+                        }, cardinality: 1
+                    }]
+                },
+                's': { //seconds || minutes
+                    validator: "[0-5][0-9]",
+                    cardinality: 2,
+                    prevalidator: [
+                        {
+                            validator: function (chrs, maskset, pos, strict, opts) {
+                                var isValid = opts.regex.mspre.test(chrs);
+                                if (!strict && !isValid) {
+                                    isValid = opts.regex.ms.test("0" + chrs);
+                                    if (isValid) {
+                                        maskset.buffer[pos] = "0";
+                                        pos++;
+                                        return { "pos": pos };
+                                    }
+                                }
+                                return isValid;
+                            }, cardinality: 1
+                        }]
+                },
+                't': { //am/pm
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        return opts.regex.ampm.test(chrs + "m");
+                    },
+                    casing: "lower",
+                    cardinality: 1
+                }
+            },
+            insertMode: false,
+            autoUnmask: false
+        },
+        'datetime12': {
+            mask: "1/2/y h:s t\\m",
+            placeholder: "dd/mm/yyyy hh:mm xm",
+            alias: "datetime",
+            hourFormat: "12"
+        },
+        'hh:mm t': {
+            mask: "h:s t\\m",
+            placeholder: "hh:mm xm",
+            alias: "datetime",
+            hourFormat: "12"
+        },
+        'h:s t': {
+            mask: "h:s t\\m",
+            placeholder: "hh:mm xm",
+            alias: "datetime",
+            hourFormat: "12"
+        },
+        'hh:mm:ss': {
+            mask: "h:s:s",
+            placeholder: "hh:mm:ss",
+            alias: "datetime",
+            autoUnmask: false
+        },
+        'hh:mm': {
+            mask: "h:s",
+            placeholder: "hh:mm",
+            alias: "datetime",
+            autoUnmask: false
+        },
+        'date': {
+            alias: "dd/mm/yyyy" // "mm/dd/yyyy"
+        },
+        'mm/yyyy': {
+            mask: "1/y",
+            placeholder: "mm/yyyy",
+            leapday: "donotuse",
+            separator: '/',
+            alias: "mm/dd/yyyy"
+        }
+    });
+}));

+ 127 - 127
js/jquery.inputmask.extensions.js

@@ -1,127 +1,127 @@
-/*
-Input Mask plugin extensions
-http://github.com/RobinHerbots/jquery.inputmask
-Copyright (c) 2010 - 2014 Robin Herbots
-Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 0.0.0
-
-Optional extensions on the jquery.inputmask base
-*/
-(function (factory) {
-    if (typeof define === 'function' && define.amd) {
-        define(['jquery', './jquery.inputmask'], factory);
-    } else {
-        factory(jQuery);
-    }
-}(function ($) {
-    //extra definitions
-    $.extend($.inputmask.defaults.definitions, {
-        'A': {
-            validator: "[A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]",
-            cardinality: 1,
-            casing: "upper" //auto uppercasing
-        },
-        '#': {
-            validator: "[0-9A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]",
-            cardinality: 1,
-            casing: "upper"
-        }
-    });
-    $.extend($.inputmask.defaults.aliases, {
-        'url': {
-            mask: "ir",
-            placeholder: "",
-            separator: "",
-            defaultPrefix: "http://",
-            regex: {
-                urlpre1: new RegExp("[fh]"),
-                urlpre2: new RegExp("(ft|ht)"),
-                urlpre3: new RegExp("(ftp|htt)"),
-                urlpre4: new RegExp("(ftp:|http|ftps)"),
-                urlpre5: new RegExp("(ftp:/|ftps:|http:|https)"),
-                urlpre6: new RegExp("(ftp://|ftps:/|http:/|https:)"),
-                urlpre7: new RegExp("(ftp://|ftps://|http://|https:/)"),
-                urlpre8: new RegExp("(ftp://|ftps://|http://|https://)")
-            },
-            definitions: {
-                'i': {
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        return true;
-                    },
-                    cardinality: 8,
-                    prevalidator: (function () {
-                        var result = [], prefixLimit = 8;
-                        for (var i = 0; i < prefixLimit; i++) {
-                            result[i] = (function () {
-                                var j = i;
-                                return {
-                                    validator: function (chrs, maskset, pos, strict, opts) {
-                                        if (opts.regex["urlpre" + (j + 1)]) {
-                                            var tmp = chrs, k;
-                                            if (((j + 1) - chrs.length) > 0) {
-                                                tmp = maskset.buffer.join('').substring(0, ((j + 1) - chrs.length)) + "" + tmp;
-                                            }
-                                            var isValid = opts.regex["urlpre" + (j + 1)].test(tmp);
-                                            if (!strict && !isValid) {
-                                                pos = pos - j;
-                                                for (k = 0; k < opts.defaultPrefix.length; k++) {
-                                                    maskset.buffer[pos] = opts.defaultPrefix[k]; pos++;
-                                                }
-                                                for (k = 0; k < tmp.length - 1; k++) {
-                                                    maskset.buffer[pos] = tmp[k]; pos++;
-                                                }
-                                                return { "pos": pos };
-                                            }
-                                            return isValid;
-                                        } else {
-                                            return false;
-                                        }
-                                    }, cardinality: j
-                                };
-                            })();
-                        }
-                        return result;
-                    })()
-                },
-                "r": {
-                    validator: ".",
-                    cardinality: 50
-                }
-            },
-            insertMode: false,
-            autoUnmask: false
-        },
-        "ip": { //ip-address mask
-            mask: "i[i[i]].i[i[i]].i[i[i]].i[i[i]]",
-            definitions: {
-                'i': {
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        if (pos - 1 > -1 && maskset.buffer[pos - 1] != ".") {
-                            chrs = maskset.buffer[pos - 1] + chrs;
-                            if (pos - 2 > -1 && maskset.buffer[pos - 2] != ".") {
-                                chrs = maskset.buffer[pos - 2] + chrs;
-                            } else chrs = "0" + chrs;
-                        } else chrs = "00" + chrs;
-                        return new RegExp("25[0-5]|2[0-4][0-9]|[01][0-9][0-9]").test(chrs);
-                    },
-                    cardinality: 1
-                }
-            }
-        },
-        "email": {
-            mask: "*{1,20}[.*{1,20}][.*{1,20}][.*{1,20}]@*{1,20}[.*{2,6}][.*{1,2}]",
-            greedy: false,
-            onBeforePaste: function (pastedValue, opts) {
-                pastedValue = pastedValue.toLowerCase();
-                return pastedValue.replace("mailto:", "");
-            },
-            definitions: {
-                '*': {
-                    validator: "[0-9A-Za-z!#$%&'*+/=?^_`{|}~\-]",
-                    cardinality: 1,
-                    casing: "lower"
-                }
-            }
-        }
-    });
-}));
+/*
+Input Mask plugin extensions
+http://github.com/RobinHerbots/jquery.inputmask
+Copyright (c) 2010 - 2014 Robin Herbots
+Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
+Version: 0.0.0
+
+Optional extensions on the jquery.inputmask base
+*/
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery', './jquery.inputmask'], factory);
+    } else {
+        factory(jQuery);
+    }
+}(function ($) {
+    //extra definitions
+    $.extend($.inputmask.defaults.definitions, {
+        'A': {
+            validator: "[A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]",
+            cardinality: 1,
+            casing: "upper" //auto uppercasing
+        },
+        '#': {
+            validator: "[0-9A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]",
+            cardinality: 1,
+            casing: "upper"
+        }
+    });
+    $.extend($.inputmask.defaults.aliases, {
+        'url': {
+            mask: "ir",
+            placeholder: "",
+            separator: "",
+            defaultPrefix: "http://",
+            regex: {
+                urlpre1: new RegExp("[fh]"),
+                urlpre2: new RegExp("(ft|ht)"),
+                urlpre3: new RegExp("(ftp|htt)"),
+                urlpre4: new RegExp("(ftp:|http|ftps)"),
+                urlpre5: new RegExp("(ftp:/|ftps:|http:|https)"),
+                urlpre6: new RegExp("(ftp://|ftps:/|http:/|https:)"),
+                urlpre7: new RegExp("(ftp://|ftps://|http://|https:/)"),
+                urlpre8: new RegExp("(ftp://|ftps://|http://|https://)")
+            },
+            definitions: {
+                'i': {
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        return true;
+                    },
+                    cardinality: 8,
+                    prevalidator: (function () {
+                        var result = [], prefixLimit = 8;
+                        for (var i = 0; i < prefixLimit; i++) {
+                            result[i] = (function () {
+                                var j = i;
+                                return {
+                                    validator: function (chrs, maskset, pos, strict, opts) {
+                                        if (opts.regex["urlpre" + (j + 1)]) {
+                                            var tmp = chrs, k;
+                                            if (((j + 1) - chrs.length) > 0) {
+                                                tmp = maskset.buffer.join('').substring(0, ((j + 1) - chrs.length)) + "" + tmp;
+                                            }
+                                            var isValid = opts.regex["urlpre" + (j + 1)].test(tmp);
+                                            if (!strict && !isValid) {
+                                                pos = pos - j;
+                                                for (k = 0; k < opts.defaultPrefix.length; k++) {
+                                                    maskset.buffer[pos] = opts.defaultPrefix[k]; pos++;
+                                                }
+                                                for (k = 0; k < tmp.length - 1; k++) {
+                                                    maskset.buffer[pos] = tmp[k]; pos++;
+                                                }
+                                                return { "pos": pos };
+                                            }
+                                            return isValid;
+                                        } else {
+                                            return false;
+                                        }
+                                    }, cardinality: j
+                                };
+                            })();
+                        }
+                        return result;
+                    })()
+                },
+                "r": {
+                    validator: ".",
+                    cardinality: 50
+                }
+            },
+            insertMode: false,
+            autoUnmask: false
+        },
+        "ip": { //ip-address mask
+            mask: "i[i[i]].i[i[i]].i[i[i]].i[i[i]]",
+            definitions: {
+                'i': {
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        if (pos - 1 > -1 && maskset.buffer[pos - 1] != ".") {
+                            chrs = maskset.buffer[pos - 1] + chrs;
+                            if (pos - 2 > -1 && maskset.buffer[pos - 2] != ".") {
+                                chrs = maskset.buffer[pos - 2] + chrs;
+                            } else chrs = "0" + chrs;
+                        } else chrs = "00" + chrs;
+                        return new RegExp("25[0-5]|2[0-4][0-9]|[01][0-9][0-9]").test(chrs);
+                    },
+                    cardinality: 1
+                }
+            }
+        },
+        "email": {
+            mask: "*{1,20}[.*{1,20}][.*{1,20}][.*{1,20}]@*{1,20}[.*{2,6}][.*{1,2}]",
+            greedy: false,
+            onBeforePaste: function (pastedValue, opts) {
+                pastedValue = pastedValue.toLowerCase();
+                return pastedValue.replace("mailto:", "");
+            },
+            definitions: {
+                '*': {
+                    validator: "[0-9A-Za-z!#$%&'*+/=?^_`{|}~\-]",
+                    cardinality: 1,
+                    casing: "lower"
+                }
+            }
+        }
+    });
+}));

+ 3 - 1
js/jquery.inputmask.js

@@ -1385,7 +1385,9 @@
                 setTimeout(function () {
                     caret(that, caret(that).begin - 1);
                     var keypress = $.Event("keypress");
-                    keypress.which = e.originalEvent.data.charCodeAt(0);
+                    keypress.which = e.originalEvent.data.charCodeAt(0);
+                    skipKeyPressEvent = false;
+                     ignorable = false;
                     keypressEvent.call(that, keypress, undefined, undefined, false);
                     var forwardPosition = getMaskSet()["p"];
                     writeBuffer(that, getBuffer(), opts.numericInput ? seekPrevious(forwardPosition) : forwardPosition);

+ 87 - 87
js/jquery.inputmask.phone.extensions.js

@@ -1,87 +1,87 @@
-/*
-Input Mask plugin extensions
-http://github.com/RobinHerbots/jquery.inputmask
-Copyright (c) 2010 - 2014 Robin Herbots
-Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 0.0.0
-
-Phone extension.
-When using this extension make sure you specify the correct url to get the masks
-
- $(selector).inputmask("phone", {
-                url: "Scripts/jquery.inputmask/phone-codes/phone-codes.json", 
-                onKeyValidation: function () { //show some metadata in the console
-                    console.log($(this).inputmask("getmetadata")["name_en"]);
-                } 
-  });
-
-
-*/
-(function (factory) {
-    if (typeof define === 'function' && define.amd) {
-        define(['jquery', './jquery.inputmask'], factory);
-    } else {
-        factory(jQuery);
-    }
-}(function ($) {
-    $.extend($.inputmask.defaults.aliases, {
-        'phone': {
-            url: "phone-codes/phone-codes.json",
-            mask: function (opts) {
-                opts.definitions = {
-                    'p': {
-                        validator: function () { return false; },
-                        cardinality: 1
-                    },
-                    '#': {
-                        validator: "[0-9]",
-                        cardinality: 1
-                    }
-                };
-                var maskList = [];
-                $.ajax({
-                    url: opts.url,
-                    async: false,
-                    dataType: 'json',
-                    success: function (response) {
-                        maskList = response;
-                    }
-                });
-
-                maskList.splice(0, 0, "+p(ppp)ppp-pppp");
-                return maskList;
-            },
-            nojumps: true,
-            nojumpsThreshold: 1
-        },
-        'phonebe': {
-            url: "phone-codes/phone-be.json",
-            mask: function (opts) {
-                opts.definitions = {
-                    'p': {
-                        validator: function () { return false; },
-                        cardinality: 1
-                    },
-                    '#': {
-                        validator: "[0-9]",
-                        cardinality: 1
-                    }
-                };
-                var maskList = [];
-                $.ajax({
-                    url: opts.url,
-                    async: false,
-                    dataType: 'json',
-                    success: function (response) {
-                        maskList = response;
-                    }
-                });
-
-                maskList.splice(0, 0, "+32(ppp)ppp-pppp");
-                return maskList;
-            },
-            nojumps: true,
-            nojumpsThreshold: 4
-        }
-    });
-}));
+/*
+Input Mask plugin extensions
+http://github.com/RobinHerbots/jquery.inputmask
+Copyright (c) 2010 - 2014 Robin Herbots
+Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
+Version: 0.0.0
+
+Phone extension.
+When using this extension make sure you specify the correct url to get the masks
+
+ $(selector).inputmask("phone", {
+                url: "Scripts/jquery.inputmask/phone-codes/phone-codes.json", 
+                onKeyValidation: function () { //show some metadata in the console
+                    console.log($(this).inputmask("getmetadata")["name_en"]);
+                } 
+  });
+
+
+*/
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery', './jquery.inputmask'], factory);
+    } else {
+        factory(jQuery);
+    }
+}(function ($) {
+    $.extend($.inputmask.defaults.aliases, {
+        'phone': {
+            url: "phone-codes/phone-codes.json",
+            mask: function (opts) {
+                opts.definitions = {
+                    'p': {
+                        validator: function () { return false; },
+                        cardinality: 1
+                    },
+                    '#': {
+                        validator: "[0-9]",
+                        cardinality: 1
+                    }
+                };
+                var maskList = [];
+                $.ajax({
+                    url: opts.url,
+                    async: false,
+                    dataType: 'json',
+                    success: function (response) {
+                        maskList = response;
+                    }
+                });
+
+                maskList.splice(0, 0, "+p(ppp)ppp-pppp");
+                return maskList;
+            },
+            nojumps: true,
+            nojumpsThreshold: 1
+        },
+        'phonebe': {
+            url: "phone-codes/phone-be.json",
+            mask: function (opts) {
+                opts.definitions = {
+                    'p': {
+                        validator: function () { return false; },
+                        cardinality: 1
+                    },
+                    '#': {
+                        validator: "[0-9]",
+                        cardinality: 1
+                    }
+                };
+                var maskList = [];
+                $.ajax({
+                    url: opts.url,
+                    async: false,
+                    dataType: 'json',
+                    success: function (response) {
+                        maskList = response;
+                    }
+                });
+
+                maskList.splice(0, 0, "+32(ppp)ppp-pppp");
+                return maskList;
+            },
+            nojumps: true,
+            nojumpsThreshold: 4
+        }
+    });
+}));

+ 193 - 193
js/jquery.inputmask.regex.extensions.js

@@ -1,193 +1,193 @@
-/*
-Input Mask plugin extensions
-http://github.com/RobinHerbots/jquery.inputmask
-Copyright (c) 2010 - 2014 Robin Herbots
-Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 0.0.0
-
-Regex extensions on the jquery.inputmask base
-Allows for using regular expressions as a mask
-*/
-(function (factory) {
-    if (typeof define === 'function' && define.amd) {
-        define(['jquery', './jquery.inputmask'], factory);
-    } else {
-        factory(jQuery);
-    }
-}(function ($) {
-    $.extend($.inputmask.defaults.aliases, { // $(selector).inputmask("Regex", { regex: "[0-9]*"}
-        'Regex': {
-            mask: "r",
-            greedy: false,
-            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]+[^,]/,
-            isComplete: function(buffer, opts){
-            	return new RegExp(opts.regex).test(buffer.join(''));
-            },
-            definitions: {
-                'r': {
-                    validator: function (chrs, maskset, pos, strict, opts) {
-                        function regexToken(isGroup, isQuantifier) {
-                            this.matches = [];
-                            this.isGroup = isGroup || false;
-                            this.isQuantifier = isQuantifier || false;
-                            this.quantifier = { min: 1, max: 1 };
-                            this.repeaterPart = undefined;
-                        }
-                        function analyseRegex() {
-                            var currentToken = new regexToken(), match, m, opengroups = [];
-
-                            opts.regexTokens = [];
-
-                            // The tokenizer regex does most of the tokenization grunt work
-                            while (match = opts.tokenizer.exec(opts.regex)) {
-                                m = match[0];
-                                switch (m.charAt(0)) {
-                                    case "(": // Group opening
-                                        opengroups.push(new regexToken(true));
-                                        break;
-                                    case ")": // Group closing
-                                        var groupToken = opengroups.pop();
-                                        if (opengroups.length > 0) {
-                                            opengroups[opengroups.length - 1]["matches"].push(groupToken);
-                                        } else {
-                                            currentToken.matches.push(groupToken);
-                                        }
-                                        break;
-                                    case "{": case "+": case "*": //Quantifier
-                                        var quantifierToken = new regexToken(false, true);
-                                        m = m.replace(/[{}]/g, "");
-                                        var mq = m.split(","), mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), mq1 = mq.length == 1 ? mq0 : (isNaN(mq[1]) ? mq[1] : parseInt(mq[1]));
-                                        quantifierToken.quantifier = { min: mq0, max: mq1 };
-                                        if (opengroups.length > 0) {
-                                            var matches = opengroups[opengroups.length - 1]["matches"];
-                                            match = matches.pop();
-                                            if (!match["isGroup"]) {
-                                                var groupToken = new regexToken(true);
-                                                groupToken.matches.push(match);
-                                                match = groupToken;
-                                            }
-                                            matches.push(match);
-                                            matches.push(quantifierToken);
-                                        } else {
-                                            match = currentToken.matches.pop();
-                                            if (!match["isGroup"]) {
-                                                var groupToken = new regexToken(true);
-                                                groupToken.matches.push(match);
-                                                match = groupToken;
-                                            }
-                                            currentToken.matches.push(match);
-                                            currentToken.matches.push(quantifierToken);
-                                        }
-                                        break;
-                                    default:
-                                        if (opengroups.length > 0) {
-                                            opengroups[opengroups.length - 1]["matches"].push(m);
-                                        } else {
-                                            currentToken.matches.push(m);
-                                        }
-                                        break;
-                                }
-                            }
-
-                            if (currentToken.matches.length > 0)
-                                opts.regexTokens.push(currentToken);
-                        };
-
-                        function validateRegexToken(token, fromGroup) {
-                            var isvalid = false;
-                            if (fromGroup) {
-                                regexPart += "(";
-                                openGroupCount++;
-                            }
-                            for (var mndx = 0; mndx < token["matches"].length; mndx++) {
-                                var matchToken = token["matches"][mndx];
-                                if (matchToken["isGroup"] == true) {
-                                    isvalid = validateRegexToken(matchToken, true);
-                                } else if (matchToken["isQuantifier"] == true) {
-                                    var crrntndx = $.inArray(matchToken, token["matches"]),
-                                        matchGroup = token["matches"][crrntndx - 1];
-                                    var regexPartBak = regexPart;
-                                    if (isNaN(matchToken.quantifier.max)) {
-                                        while (matchToken["repeaterPart"] && matchToken["repeaterPart"] != regexPart && matchToken["repeaterPart"].length > regexPart.length) {
-                                            isvalid = validateRegexToken(matchGroup, true);
-                                            if (isvalid) break;
-                                        }
-                                        isvalid = isvalid || validateRegexToken(matchGroup, true);
-                                        if (isvalid) matchToken["repeaterPart"] = regexPart;
-                                        regexPart = regexPartBak + matchToken.quantifier.max;
-                                    } else {
-                                        for (var i = 0, qm = matchToken.quantifier.max - 1; i < qm; i++) {
-                                            isvalid = validateRegexToken(matchGroup, true);
-                                            if (isvalid) break;
-                                        }
-                                        regexPart = regexPartBak + "{" + matchToken.quantifier.min + "," + matchToken.quantifier.max + "}";
-                                    }
-                                } else if (matchToken["matches"] != undefined) {
-                                    for (var k = 0; k < matchToken.length; k++) {
-                                        isvalid = validateRegexToken(matchToken[k], fromGroup);
-                                        if (isvalid) break;
-                                    }
-                                } else {
-                                    var testExp;
-                                    if (matchToken.charAt(0) == "[") {
-                                        testExp = regexPart;
-                                        testExp += matchToken;
-                                        for (var j = 0; j < openGroupCount; j++) {
-                                            testExp += ")";
-                                        }
-                                        var exp = new RegExp("^(" + testExp + ")$");
-                                        isvalid = exp.test(bufferStr);
-                                    } else {
-                                        for (var l = 0, tl = matchToken.length; l < tl; l++) {
-                                            if (matchToken.charAt(l) == "\\") continue;
-                                            testExp = regexPart;
-                                            testExp += matchToken.substr(0, l + 1);
-                                            testExp = testExp.replace(/\|$/, "");
-                                            for (var j = 0; j < openGroupCount; j++) {
-                                                testExp += ")";
-                                            }
-                                            var exp = new RegExp("^(" + testExp + ")$");
-                                            isvalid = exp.test(bufferStr);
-                                            if (isvalid) break;
-                                        }
-                                    }
-                                    regexPart += matchToken;
-                                }
-                                if (isvalid) break;
-                            }
-
-                            if (fromGroup) {
-                                regexPart += ")";
-                                openGroupCount--;
-                            }
-
-                            return isvalid;
-                        }
-
-
-                        if (opts.regexTokens == null) {
-                            analyseRegex();
-                        }
-
-                        var cbuffer = maskset.buffer.slice(), regexPart = "", isValid = false, openGroupCount = 0;
-                        cbuffer.splice(pos, 0, chrs);
-                        var bufferStr = cbuffer.join('');
-                        for (var i = 0; i < opts.regexTokens.length; i++) {
-                            var regexToken = opts.regexTokens[i];
-                            isValid = validateRegexToken(regexToken, regexToken["isGroup"]);
-                            if (isValid) break;
-                        }
-
-                        return isValid;
-                    },
-                    cardinality: 1
-                }
-            }
-        }
-    });
-}));
+/*
+Input Mask plugin extensions
+http://github.com/RobinHerbots/jquery.inputmask
+Copyright (c) 2010 - 2014 Robin Herbots
+Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
+Version: 0.0.0
+
+Regex extensions on the jquery.inputmask base
+Allows for using regular expressions as a mask
+*/
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(['jquery', './jquery.inputmask'], factory);
+    } else {
+        factory(jQuery);
+    }
+}(function ($) {
+    $.extend($.inputmask.defaults.aliases, { // $(selector).inputmask("Regex", { regex: "[0-9]*"}
+        'Regex': {
+            mask: "r",
+            greedy: false,
+            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]+[^,]/,
+            isComplete: function(buffer, opts){
+            	return new RegExp(opts.regex).test(buffer.join(''));
+            },
+            definitions: {
+                'r': {
+                    validator: function (chrs, maskset, pos, strict, opts) {
+                        function regexToken(isGroup, isQuantifier) {
+                            this.matches = [];
+                            this.isGroup = isGroup || false;
+                            this.isQuantifier = isQuantifier || false;
+                            this.quantifier = { min: 1, max: 1 };
+                            this.repeaterPart = undefined;
+                        }
+                        function analyseRegex() {
+                            var currentToken = new regexToken(), match, m, opengroups = [];
+
+                            opts.regexTokens = [];
+
+                            // The tokenizer regex does most of the tokenization grunt work
+                            while (match = opts.tokenizer.exec(opts.regex)) {
+                                m = match[0];
+                                switch (m.charAt(0)) {
+                                    case "(": // Group opening
+                                        opengroups.push(new regexToken(true));
+                                        break;
+                                    case ")": // Group closing
+                                        var groupToken = opengroups.pop();
+                                        if (opengroups.length > 0) {
+                                            opengroups[opengroups.length - 1]["matches"].push(groupToken);
+                                        } else {
+                                            currentToken.matches.push(groupToken);
+                                        }
+                                        break;
+                                    case "{": case "+": case "*": //Quantifier
+                                        var quantifierToken = new regexToken(false, true);
+                                        m = m.replace(/[{}]/g, "");
+                                        var mq = m.split(","), mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), mq1 = mq.length == 1 ? mq0 : (isNaN(mq[1]) ? mq[1] : parseInt(mq[1]));
+                                        quantifierToken.quantifier = { min: mq0, max: mq1 };
+                                        if (opengroups.length > 0) {
+                                            var matches = opengroups[opengroups.length - 1]["matches"];
+                                            match = matches.pop();
+                                            if (!match["isGroup"]) {
+                                                var groupToken = new regexToken(true);
+                                                groupToken.matches.push(match);
+                                                match = groupToken;
+                                            }
+                                            matches.push(match);
+                                            matches.push(quantifierToken);
+                                        } else {
+                                            match = currentToken.matches.pop();
+                                            if (!match["isGroup"]) {
+                                                var groupToken = new regexToken(true);
+                                                groupToken.matches.push(match);
+                                                match = groupToken;
+                                            }
+                                            currentToken.matches.push(match);
+                                            currentToken.matches.push(quantifierToken);
+                                        }
+                                        break;
+                                    default:
+                                        if (opengroups.length > 0) {
+                                            opengroups[opengroups.length - 1]["matches"].push(m);
+                                        } else {
+                                            currentToken.matches.push(m);
+                                        }
+                                        break;
+                                }
+                            }
+
+                            if (currentToken.matches.length > 0)
+                                opts.regexTokens.push(currentToken);
+                        };
+
+                        function validateRegexToken(token, fromGroup) {
+                            var isvalid = false;
+                            if (fromGroup) {
+                                regexPart += "(";
+                                openGroupCount++;
+                            }
+                            for (var mndx = 0; mndx < token["matches"].length; mndx++) {
+                                var matchToken = token["matches"][mndx];
+                                if (matchToken["isGroup"] == true) {
+                                    isvalid = validateRegexToken(matchToken, true);
+                                } else if (matchToken["isQuantifier"] == true) {
+                                    var crrntndx = $.inArray(matchToken, token["matches"]),
+                                        matchGroup = token["matches"][crrntndx - 1];
+                                    var regexPartBak = regexPart;
+                                    if (isNaN(matchToken.quantifier.max)) {
+                                        while (matchToken["repeaterPart"] && matchToken["repeaterPart"] != regexPart && matchToken["repeaterPart"].length > regexPart.length) {
+                                            isvalid = validateRegexToken(matchGroup, true);
+                                            if (isvalid) break;
+                                        }
+                                        isvalid = isvalid || validateRegexToken(matchGroup, true);
+                                        if (isvalid) matchToken["repeaterPart"] = regexPart;
+                                        regexPart = regexPartBak + matchToken.quantifier.max;
+                                    } else {
+                                        for (var i = 0, qm = matchToken.quantifier.max - 1; i < qm; i++) {
+                                            isvalid = validateRegexToken(matchGroup, true);
+                                            if (isvalid) break;
+                                        }
+                                        regexPart = regexPartBak + "{" + matchToken.quantifier.min + "," + matchToken.quantifier.max + "}";
+                                    }
+                                } else if (matchToken["matches"] != undefined) {
+                                    for (var k = 0; k < matchToken.length; k++) {
+                                        isvalid = validateRegexToken(matchToken[k], fromGroup);
+                                        if (isvalid) break;
+                                    }
+                                } else {
+                                    var testExp;
+                                    if (matchToken.charAt(0) == "[") {
+                                        testExp = regexPart;
+                                        testExp += matchToken;
+                                        for (var j = 0; j < openGroupCount; j++) {
+                                            testExp += ")";
+                                        }
+                                        var exp = new RegExp("^(" + testExp + ")$");
+                                        isvalid = exp.test(bufferStr);
+                                    } else {
+                                        for (var l = 0, tl = matchToken.length; l < tl; l++) {
+                                            if (matchToken.charAt(l) == "\\") continue;
+                                            testExp = regexPart;
+                                            testExp += matchToken.substr(0, l + 1);
+                                            testExp = testExp.replace(/\|$/, "");
+                                            for (var j = 0; j < openGroupCount; j++) {
+                                                testExp += ")";
+                                            }
+                                            var exp = new RegExp("^(" + testExp + ")$");
+                                            isvalid = exp.test(bufferStr);
+                                            if (isvalid) break;
+                                        }
+                                    }
+                                    regexPart += matchToken;
+                                }
+                                if (isvalid) break;
+                            }
+
+                            if (fromGroup) {
+                                regexPart += ")";
+                                openGroupCount--;
+                            }
+
+                            return isvalid;
+                        }
+
+
+                        if (opts.regexTokens == null) {
+                            analyseRegex();
+                        }
+
+                        var cbuffer = maskset.buffer.slice(), regexPart = "", isValid = false, openGroupCount = 0;
+                        cbuffer.splice(pos, 0, chrs);
+                        var bufferStr = cbuffer.join('');
+                        for (var i = 0; i < opts.regexTokens.length; i++) {
+                            var regexToken = opts.regexTokens[i];
+                            isValid = validateRegexToken(regexToken, regexToken["isGroup"]);
+                            if (isValid) break;
+                        }
+
+                        return isValid;
+                    },
+                    cardinality: 1
+                }
+            }
+        }
+    });
+}));

+ 38 - 38
package.json

@@ -1,38 +1,38 @@
-{
-  "name": "jquery.inputmask",
-  "version": "3.0.64",
-  "description": "jquery.inputmask is a jquery plugin which create an input mask.",
-  "main": [
-    "./dist/inputmask/jquery.inputmask.js",
-    "./dist/inputmask/jquery.inputmask.extensions.js",
-	"./dist/inputmask/jquery.inputmask.date.extensions.js",
-	"./dist/inputmask/jquery.inputmask.numeric.extensions.js",
-	"./dist/inputmask/jquery.inputmask.phone.extensions.js",
-	"./dist/inputmask/jquery.inputmask.regex.extensions.js"
-  ],
-  "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
-  },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/RobinHerbots/jquery.inputmask.git"
-  },
-  "keywords": [
-    "input",
-    "form",
-    "inputmask",
-    "mask"
-  ],
-  "author": {
-    "name": "Robin Herbots",
-    "url": "http://github.com/RobinHerbots/jquery.inputmask"
-  },
-  "license": "MIT",
-  "bugs": {
-    "url": "https://github.com/RobinHerbots/jquery.inputmask/issues"
-  },
-  "homepage": "https://github.com/RobinHerbots/jquery.inputmask",
-  "dependencies": {
-    "jquery": ">=1.7"
-  }
-}
+{
+  "name": "jquery.inputmask",
+  "version": "3.0.65",
+  "description": "jquery.inputmask is a jquery plugin which create an input mask.",
+  "main": [
+    "./dist/inputmask/jquery.inputmask.js",
+    "./dist/inputmask/jquery.inputmask.extensions.js",
+	"./dist/inputmask/jquery.inputmask.date.extensions.js",
+	"./dist/inputmask/jquery.inputmask.numeric.extensions.js",
+	"./dist/inputmask/jquery.inputmask.phone.extensions.js",
+	"./dist/inputmask/jquery.inputmask.regex.extensions.js"
+  ],
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/RobinHerbots/jquery.inputmask.git"
+  },
+  "keywords": [
+    "input",
+    "form",
+    "inputmask",
+    "mask"
+  ],
+  "author": {
+    "name": "Robin Herbots",
+    "url": "http://github.com/RobinHerbots/jquery.inputmask"
+  },
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/RobinHerbots/jquery.inputmask/issues"
+  },
+  "homepage": "https://github.com/RobinHerbots/jquery.inputmask",
+  "dependencies": {
+    "jquery": ">=1.7"
+  }
+}

+ 13 - 13
qunit/tests_keepStatic.js

@@ -1,13 +1,13 @@
-module("keepStatic mask switching");
-
-test("{ mask: [\"+55-99-9999-9999\", \"+55-99-99999-9999\", ], keepStatic: true }", function () {
-    var $fixture = $("#qunit-fixture");
-    $fixture.append('<input type="text" id="testmask" />');
-    $("#testmask").inputmask({ mask: ["+55-99-9999-9999", "+55-99-99999-9999"], keepStatic: true });
-    $("#testmask")[0].focus();
-    $("#testmask").Type("12123451234");
-
-    equal(document.getElementById("testmask")._valueGet(), "+55-12-12345-1234", "Result " + document.getElementById("testmask")._valueGet());
-
-    $("#testmask").remove();
-});
+module("keepStatic mask switching");
+
+test("{ mask: [\"+55-99-9999-9999\", \"+55-99-99999-9999\", ], keepStatic: true }", function () {
+    var $fixture = $("#qunit-fixture");
+    $fixture.append('<input type="text" id="testmask" />');
+    $("#testmask").inputmask({ mask: ["+55-99-9999-9999", "+55-99-99999-9999"], keepStatic: true });
+    $("#testmask")[0].focus();
+    $("#testmask").Type("12123451234");
+
+    equal(document.getElementById("testmask")._valueGet(), "+55-12-12345-1234", "Result " + document.getElementById("testmask")._valueGet());
+
+    $("#testmask").remove();
+});