Browse Source

optimize alternator + setvalidposition

Robin Herbots 11 years ago
parent
commit
0345102217

+ 32 - 35
dist/inputmask/jquery.inputmask.js

@@ -232,12 +232,13 @@
                 var i, positionsClone = $.extend(!0, {}, getMaskSet().validPositions), lvp = getLastValidPosition();
                 for (i = pos; lvp >= i; i++) delete getMaskSet().validPositions[i];
                 getMaskSet().validPositions[pos] = validTest;
-                var valid = !0;
+                var j, valid = !0;
                 for (i = pos; lvp >= i; i++) {
                     var t = positionsClone[i];
                     if (void 0 != t) {
-                        var j = null == t.match.fn ? i + 1 : seekNext(i);
-                        valid = positionCanMatchDefinition(j, t.match.def) ? valid && isValid(j, t.input, !0, !0) !== !1 : !1;
+                        var vps = getMaskSet().validPositions;
+                        j = !opts.keepStatic && (void 0 != vps[i + 1] && getTests(i + 1, vps[i].locator.slice(), i).length > 1 || vps[i] && void 0 != vps[i].alternation) ? i + 1 : seekNext(i), 
+                        valid = positionCanMatchDefinition(j, t.match.def) ? valid && isValid(j, t.input, !0, !0) !== !1 : null == t.match.fn;
                     }
                     if (!valid) break;
                 }
@@ -430,44 +431,38 @@
                 }), rslt;
             }
             function alternate(pos, c, strict, fromSetValid) {
-                if (opts.keepStatic) {
-                    var lastAlt, alternation, validPsClone = $.extend(!0, {}, getMaskSet().validPositions);
-                    for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) if (getMaskSet().validPositions[lastAlt] && void 0 != getMaskSet().validPositions[lastAlt].alternation) {
-                        alternation = getMaskSet().validPositions[lastAlt].alternation;
-                        break;
-                    }
-                    if (void 0 != alternation) for (var decisionPos in getMaskSet().validPositions) if (parseInt(decisionPos) > parseInt(lastAlt) && void 0 === getMaskSet().validPositions[decisionPos].alternation) {
-                        for (var altPos = getMaskSet().validPositions[decisionPos], decisionTaker = altPos.locator[alternation], altNdxs = getMaskSet().validPositions[lastAlt].locator[alternation].split(","), mndx = 0; mndx < altNdxs.length; mndx++) if (decisionTaker < altNdxs[mndx]) {
-                            for (var possibilityPos, possibilities, dp = decisionPos - 1; dp >= 0; dp--) if (possibilityPos = getMaskSet().validPositions[dp], 
-                            void 0 != possibilityPos) {
-                                possibilities = possibilityPos.locator[alternation], possibilityPos.locator[alternation] = altNdxs[mndx];
-                                break;
-                            }
-                            if (decisionTaker != possibilityPos.locator[alternation]) {
-                                for (var buffer = getBuffer().slice(), i = decisionPos; i < getLastValidPosition() + 1; i++) delete getMaskSet().validPositions[i], 
-                                delete getMaskSet().tests[i];
-                                resetMaskSet(!0), opts.keepStatic = !opts.keepStatic;
-                                for (var i = decisionPos; i < buffer.length; i++) buffer[i] != opts.skipOptionalPartCharacter && isValid(getLastValidPosition() + 1, buffer[i], !1, !0);
-                                possibilityPos.locator[alternation] = possibilities;
-                                var isValidRslt = getLastValidPosition() + 1 == pos && isValid(pos, c, strict, fromSetValid);
-                                if (opts.keepStatic = !opts.keepStatic, isValidRslt) return isValidRslt;
-                                resetMaskSet(), getMaskSet().validPositions = $.extend(!0, {}, validPsClone);
-                            }
+                var lastAlt, alternation, validPsClone = $.extend(!0, {}, getMaskSet().validPositions);
+                for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) if (getMaskSet().validPositions[lastAlt] && void 0 != getMaskSet().validPositions[lastAlt].alternation) {
+                    alternation = getMaskSet().validPositions[lastAlt].alternation;
+                    break;
+                }
+                if (void 0 != alternation) for (var decisionPos in getMaskSet().validPositions) if (parseInt(decisionPos) > parseInt(lastAlt) && void 0 === getMaskSet().validPositions[decisionPos].alternation) {
+                    for (var altPos = getMaskSet().validPositions[decisionPos], decisionTaker = altPos.locator[alternation], altNdxs = getMaskSet().validPositions[lastAlt].locator[alternation].split(","), mndx = 0; mndx < altNdxs.length; mndx++) if (decisionTaker < altNdxs[mndx]) {
+                        for (var possibilityPos, possibilities, dp = decisionPos - 1; dp >= 0; dp--) if (possibilityPos = getMaskSet().validPositions[dp], 
+                        void 0 != possibilityPos) {
+                            possibilities = possibilityPos.locator[alternation], possibilityPos.locator[alternation] = altNdxs[mndx];
+                            break;
+                        }
+                        if (decisionTaker != possibilityPos.locator[alternation]) {
+                            for (var buffer = getBuffer().slice(), i = decisionPos; i < getLastValidPosition() + 1; i++) delete getMaskSet().validPositions[i], 
+                            delete getMaskSet().tests[i];
+                            resetMaskSet(!0), opts.keepStatic = !opts.keepStatic;
+                            for (var i = decisionPos; i < buffer.length; i++) buffer[i] != opts.skipOptionalPartCharacter && isValid(getLastValidPosition() + 1, buffer[i], !1, !0);
+                            possibilityPos.locator[alternation] = possibilities;
+                            var isValidRslt = isValid(pos, c, strict, fromSetValid);
+                            if (opts.keepStatic = !opts.keepStatic, isValidRslt) return isValidRslt;
+                            resetMaskSet(), getMaskSet().validPositions = $.extend(!0, {}, validPsClone);
                         }
-                        break;
                     }
+                    break;
                 }
                 return !1;
             }
             strict = strict === !0;
             for (var buffer = getBuffer(), pndx = pos - 1; pndx > -1 && (!getMaskSet().validPositions[pndx] || null != getMaskSet().validPositions[pndx].match.fn); pndx--) void 0 == getMaskSet().validPositions[pndx] && (!isMask(pndx) || buffer[pndx] != getPlaceholder(pndx)) && getTests(pndx).length > 1 && _isValid(pndx, buffer[pndx], !0);
-            var maskPos = pos;
-            if (maskPos >= getMaskLength()) {
-                if (!fromSetValid) return alternate(pos, c, strict, fromSetValid);
-                if (resetMaskSet(!0), maskPos >= getMaskLength()) return alternate(pos, c, strict, fromSetValid);
-            }
-            var result = _isValid(maskPos, c, strict, fromSetValid);
-            if (!strict && result === !1) {
+            var maskPos = pos, result = !1;
+            if (fromSetValid && maskPos >= getMaskLength() && resetMaskSet(!0), maskPos < getMaskLength() && (result = _isValid(maskPos, c, strict, fromSetValid), 
+            !strict && result === !1)) {
                 var currentPosValid = getMaskSet().validPositions[maskPos];
                 if (!currentPosValid || null != currentPosValid.match.fn || currentPosValid.match.def != c && c != opts.skipOptionalPartCharacter) {
                     if ((opts.insertMode || void 0 == getMaskSet().validPositions[seekNext(maskPos)]) && !isMask(maskPos)) for (var nPos = maskPos + 1, snPos = seekNext(maskPos); snPos >= nPos; nPos++) if (result = _isValid(nPos, c, strict, fromSetValid), 
@@ -479,7 +474,8 @@
                     caret: seekNext(maskPos)
                 };
             }
-            return result === !0 && (result = {
+            return result === !1 && opts.keepStatic && isComplete(buffer) && (result = alternate(pos, c, strict, fromSetValid)), 
+            result === !0 && (result = {
                 pos: maskPos
             }), result;
         }
@@ -695,6 +691,7 @@
         function handleRemove(input, k, pos) {
             function generalize() {
                 if (opts.keepStatic) {
+                    resetMaskSet(!0);
                     var lastAlt, validInputs = [];
                     for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) if (getMaskSet().validPositions[lastAlt]) {
                         if (void 0 != getMaskSet().validPositions[lastAlt].alternation) break;

+ 32 - 35
dist/jquery.inputmask.bundle.js

@@ -230,12 +230,13 @@
                 var i, positionsClone = $.extend(!0, {}, getMaskSet().validPositions), lvp = getLastValidPosition();
                 for (i = pos; lvp >= i; i++) delete getMaskSet().validPositions[i];
                 getMaskSet().validPositions[pos] = validTest;
-                var valid = !0;
+                var j, valid = !0;
                 for (i = pos; lvp >= i; i++) {
                     var t = positionsClone[i];
                     if (void 0 != t) {
-                        var j = null == t.match.fn ? i + 1 : seekNext(i);
-                        valid = positionCanMatchDefinition(j, t.match.def) ? valid && isValid(j, t.input, !0, !0) !== !1 : !1;
+                        var vps = getMaskSet().validPositions;
+                        j = !opts.keepStatic && (void 0 != vps[i + 1] && getTests(i + 1, vps[i].locator.slice(), i).length > 1 || vps[i] && void 0 != vps[i].alternation) ? i + 1 : seekNext(i), 
+                        valid = positionCanMatchDefinition(j, t.match.def) ? valid && isValid(j, t.input, !0, !0) !== !1 : null == t.match.fn;
                     }
                     if (!valid) break;
                 }
@@ -428,44 +429,38 @@
                 }), rslt;
             }
             function alternate(pos, c, strict, fromSetValid) {
-                if (opts.keepStatic) {
-                    var lastAlt, alternation, validPsClone = $.extend(!0, {}, getMaskSet().validPositions);
-                    for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) if (getMaskSet().validPositions[lastAlt] && void 0 != getMaskSet().validPositions[lastAlt].alternation) {
-                        alternation = getMaskSet().validPositions[lastAlt].alternation;
-                        break;
-                    }
-                    if (void 0 != alternation) for (var decisionPos in getMaskSet().validPositions) if (parseInt(decisionPos) > parseInt(lastAlt) && void 0 === getMaskSet().validPositions[decisionPos].alternation) {
-                        for (var altPos = getMaskSet().validPositions[decisionPos], decisionTaker = altPos.locator[alternation], altNdxs = getMaskSet().validPositions[lastAlt].locator[alternation].split(","), mndx = 0; mndx < altNdxs.length; mndx++) if (decisionTaker < altNdxs[mndx]) {
-                            for (var possibilityPos, possibilities, dp = decisionPos - 1; dp >= 0; dp--) if (possibilityPos = getMaskSet().validPositions[dp], 
-                            void 0 != possibilityPos) {
-                                possibilities = possibilityPos.locator[alternation], possibilityPos.locator[alternation] = altNdxs[mndx];
-                                break;
-                            }
-                            if (decisionTaker != possibilityPos.locator[alternation]) {
-                                for (var buffer = getBuffer().slice(), i = decisionPos; i < getLastValidPosition() + 1; i++) delete getMaskSet().validPositions[i], 
-                                delete getMaskSet().tests[i];
-                                resetMaskSet(!0), opts.keepStatic = !opts.keepStatic;
-                                for (var i = decisionPos; i < buffer.length; i++) buffer[i] != opts.skipOptionalPartCharacter && isValid(getLastValidPosition() + 1, buffer[i], !1, !0);
-                                possibilityPos.locator[alternation] = possibilities;
-                                var isValidRslt = getLastValidPosition() + 1 == pos && isValid(pos, c, strict, fromSetValid);
-                                if (opts.keepStatic = !opts.keepStatic, isValidRslt) return isValidRslt;
-                                resetMaskSet(), getMaskSet().validPositions = $.extend(!0, {}, validPsClone);
-                            }
+                var lastAlt, alternation, validPsClone = $.extend(!0, {}, getMaskSet().validPositions);
+                for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) if (getMaskSet().validPositions[lastAlt] && void 0 != getMaskSet().validPositions[lastAlt].alternation) {
+                    alternation = getMaskSet().validPositions[lastAlt].alternation;
+                    break;
+                }
+                if (void 0 != alternation) for (var decisionPos in getMaskSet().validPositions) if (parseInt(decisionPos) > parseInt(lastAlt) && void 0 === getMaskSet().validPositions[decisionPos].alternation) {
+                    for (var altPos = getMaskSet().validPositions[decisionPos], decisionTaker = altPos.locator[alternation], altNdxs = getMaskSet().validPositions[lastAlt].locator[alternation].split(","), mndx = 0; mndx < altNdxs.length; mndx++) if (decisionTaker < altNdxs[mndx]) {
+                        for (var possibilityPos, possibilities, dp = decisionPos - 1; dp >= 0; dp--) if (possibilityPos = getMaskSet().validPositions[dp], 
+                        void 0 != possibilityPos) {
+                            possibilities = possibilityPos.locator[alternation], possibilityPos.locator[alternation] = altNdxs[mndx];
+                            break;
+                        }
+                        if (decisionTaker != possibilityPos.locator[alternation]) {
+                            for (var buffer = getBuffer().slice(), i = decisionPos; i < getLastValidPosition() + 1; i++) delete getMaskSet().validPositions[i], 
+                            delete getMaskSet().tests[i];
+                            resetMaskSet(!0), opts.keepStatic = !opts.keepStatic;
+                            for (var i = decisionPos; i < buffer.length; i++) buffer[i] != opts.skipOptionalPartCharacter && isValid(getLastValidPosition() + 1, buffer[i], !1, !0);
+                            possibilityPos.locator[alternation] = possibilities;
+                            var isValidRslt = isValid(pos, c, strict, fromSetValid);
+                            if (opts.keepStatic = !opts.keepStatic, isValidRslt) return isValidRslt;
+                            resetMaskSet(), getMaskSet().validPositions = $.extend(!0, {}, validPsClone);
                         }
-                        break;
                     }
+                    break;
                 }
                 return !1;
             }
             strict = strict === !0;
             for (var buffer = getBuffer(), pndx = pos - 1; pndx > -1 && (!getMaskSet().validPositions[pndx] || null != getMaskSet().validPositions[pndx].match.fn); pndx--) void 0 == getMaskSet().validPositions[pndx] && (!isMask(pndx) || buffer[pndx] != getPlaceholder(pndx)) && getTests(pndx).length > 1 && _isValid(pndx, buffer[pndx], !0);
-            var maskPos = pos;
-            if (maskPos >= getMaskLength()) {
-                if (!fromSetValid) return alternate(pos, c, strict, fromSetValid);
-                if (resetMaskSet(!0), maskPos >= getMaskLength()) return alternate(pos, c, strict, fromSetValid);
-            }
-            var result = _isValid(maskPos, c, strict, fromSetValid);
-            if (!strict && result === !1) {
+            var maskPos = pos, result = !1;
+            if (fromSetValid && maskPos >= getMaskLength() && resetMaskSet(!0), maskPos < getMaskLength() && (result = _isValid(maskPos, c, strict, fromSetValid), 
+            !strict && result === !1)) {
                 var currentPosValid = getMaskSet().validPositions[maskPos];
                 if (!currentPosValid || null != currentPosValid.match.fn || currentPosValid.match.def != c && c != opts.skipOptionalPartCharacter) {
                     if ((opts.insertMode || void 0 == getMaskSet().validPositions[seekNext(maskPos)]) && !isMask(maskPos)) for (var nPos = maskPos + 1, snPos = seekNext(maskPos); snPos >= nPos; nPos++) if (result = _isValid(nPos, c, strict, fromSetValid), 
@@ -477,7 +472,8 @@
                     caret: seekNext(maskPos)
                 };
             }
-            return result === !0 && (result = {
+            return result === !1 && opts.keepStatic && isComplete(buffer) && (result = alternate(pos, c, strict, fromSetValid)), 
+            result === !0 && (result = {
                 pos: maskPos
             }), result;
         }
@@ -693,6 +689,7 @@
         function handleRemove(input, k, pos) {
             function generalize() {
                 if (opts.keepStatic) {
+                    resetMaskSet(!0);
                     var lastAlt, validInputs = [];
                     for (lastAlt = getLastValidPosition(); lastAlt >= 0; lastAlt--) if (getMaskSet().validPositions[lastAlt]) {
                         if (void 0 != getMaskSet().validPositions[lastAlt].alternation) break;

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


+ 77 - 72
js/jquery.inputmask.js

@@ -398,14 +398,19 @@
                         delete getMaskSet()["validPositions"][i];
                     }
                     getMaskSet()["validPositions"][pos] = validTest;
-                    var valid = true;
+                    var valid = true, j;
                     for (i = pos; i <= lvp ; i++) {
                         var t = positionsClone[i];
                         if (t != undefined) {
-                            var j = t["match"].fn == null ? i + 1 : seekNext(i);
+                            var vps = getMaskSet()["validPositions"];
+                            if (!opts.keepStatic && (vps[i + 1] != undefined && getTests(i + 1, vps[i].locator.slice(), i).length > 1 || (vps[i] && vps[i].alternation != undefined)))
+                                j = i + 1;
+                            else
+                                j = seekNext(i);
+
                             if (positionCanMatchDefinition(j, t["match"].def)) {
-                                valid = valid && isValid(j, t["input"], true, true) !== false;
-                            } else valid = false;
+                                valid = valid && (isValid(j, t["input"], true, true) !== false);
+                            } else valid = t["match"].fn == null;
                         }
                         if (!valid) break;
                     }
@@ -766,62 +771,60 @@
                     return rslt;
                 }
                 function alternate(pos, c, strict, fromSetValid) {
-                    if (opts.keepStatic) {
-                        var validPsClone = $.extend(true, {}, getMaskSet()["validPositions"]),
-                            lastAlt,
-                            alternation;
-                        //find last alternation
-                        for (lastAlt = getLastValidPosition() ; lastAlt >= 0; lastAlt--) {
-                            if (getMaskSet()["validPositions"][lastAlt] && getMaskSet()["validPositions"][lastAlt].alternation != undefined) {
-                                alternation = getMaskSet()["validPositions"][lastAlt].alternation;
-                                break;
-                            }
+                    var validPsClone = $.extend(true, {}, getMaskSet()["validPositions"]),
+                        lastAlt,
+                        alternation;
+                    //find last alternation
+                    for (lastAlt = getLastValidPosition() ; lastAlt >= 0; lastAlt--) {
+                        if (getMaskSet()["validPositions"][lastAlt] && getMaskSet()["validPositions"][lastAlt].alternation != undefined) {
+                            alternation = getMaskSet()["validPositions"][lastAlt].alternation;
+                            break;
                         }
-                        if (alternation != undefined) {
-                            //find first decision making position
-                            for (var decisionPos in getMaskSet()["validPositions"]) {
-                                if (parseInt(decisionPos) > parseInt(lastAlt) && getMaskSet()["validPositions"][decisionPos].alternation === undefined) {
-                                    var altPos = getMaskSet()["validPositions"][decisionPos],
-                                        decisionTaker = altPos.locator[alternation],
-                                        altNdxs = getMaskSet()["validPositions"][lastAlt].locator[alternation].split(",");
-
-                                    for (var mndx = 0; mndx < altNdxs.length; mndx++) {
-                                        if (decisionTaker < altNdxs[mndx]) {
-                                            var possibilityPos, possibilities;
-                                            for (var dp = decisionPos - 1; dp >= 0; dp--) {
-                                                possibilityPos = getMaskSet()["validPositions"][dp];
-                                                if (possibilityPos != undefined) {
-                                                    possibilities = possibilityPos.locator[alternation]; //store to reset 
-                                                    possibilityPos.locator[alternation] = altNdxs[mndx];
-                                                    break;
-                                                }
+                    }
+                    if (alternation != undefined) {
+                        //find first decision making position
+                        for (var decisionPos in getMaskSet()["validPositions"]) {
+                            if (parseInt(decisionPos) > parseInt(lastAlt) && getMaskSet()["validPositions"][decisionPos].alternation === undefined) {
+                                var altPos = getMaskSet()["validPositions"][decisionPos],
+                                    decisionTaker = altPos.locator[alternation],
+                                    altNdxs = getMaskSet()["validPositions"][lastAlt].locator[alternation].split(",");
+
+                                for (var mndx = 0; mndx < altNdxs.length; mndx++) {
+                                    if (decisionTaker < altNdxs[mndx]) {
+                                        var possibilityPos, possibilities;
+                                        for (var dp = decisionPos - 1; dp >= 0; dp--) {
+                                            possibilityPos = getMaskSet()["validPositions"][dp];
+                                            if (possibilityPos != undefined) {
+                                                possibilities = possibilityPos.locator[alternation]; //store to reset 
+                                                possibilityPos.locator[alternation] = altNdxs[mndx];
+                                                break;
                                             }
-                                            if (decisionTaker != possibilityPos.locator[alternation]) {
-                                                var buffer = getBuffer().slice(); //work on clone
-                                                for (var i = decisionPos; i < getLastValidPosition() + 1; i++) {
-                                                    delete getMaskSet()["validPositions"][i];
-                                                    delete getMaskSet()["tests"][i];
-                                                }
-                                                resetMaskSet(true); //clear getbuffer
-                                                opts.keepStatic = !opts.keepStatic; //disable keepStatic on getMaskLength
-                                                for (var i = decisionPos; i < buffer.length; i++) {
-                                                    if (buffer[i] != opts.skipOptionalPartCharacter) {
-                                                        isValid(getLastValidPosition() + 1, buffer[i], false, true);
-                                                    }
+                                        }
+                                        if (decisionTaker != possibilityPos.locator[alternation]) {
+                                            var buffer = getBuffer().slice(); //work on clone
+                                            for (var i = decisionPos; i < getLastValidPosition() + 1; i++) {
+                                                delete getMaskSet()["validPositions"][i];
+                                                delete getMaskSet()["tests"][i];
+                                            }
+                                            resetMaskSet(true); //clear getbuffer
+                                            opts.keepStatic = !opts.keepStatic; //disable keepStatic on getMaskLength
+                                            for (var i = decisionPos; i < buffer.length; i++) {
+                                                if (buffer[i] != opts.skipOptionalPartCharacter) {
+                                                    isValid(getLastValidPosition() + 1, buffer[i], false, true);
                                                 }
-                                                possibilityPos.locator[alternation] = possibilities; //reset forceddecision ~ needed for proper delete
-                                                var isValidRslt = getLastValidPosition() + 1 == pos && isValid(pos, c, strict, fromSetValid);
-                                                opts.keepStatic = !opts.keepStatic; //enable keepStatic on getMaskLength
-                                                if (!isValidRslt) {
-                                                    resetMaskSet();
-                                                    getMaskSet()["validPositions"] = $.extend(true, {}, validPsClone);
-                                                } else
-                                                    return isValidRslt;
                                             }
+                                            possibilityPos.locator[alternation] = possibilities; //reset forceddecision ~ needed for proper delete
+                                            var isValidRslt = isValid(pos, c, strict, fromSetValid);
+                                            opts.keepStatic = !opts.keepStatic; //enable keepStatic on getMaskLength
+                                            if (!isValidRslt) {
+                                                resetMaskSet();
+                                                getMaskSet()["validPositions"] = $.extend(true, {}, validPsClone);
+                                            } else
+                                                return isValidRslt;
                                         }
                                     }
-                                    break;
                                 }
+                                break;
                             }
                         }
                     }
@@ -838,30 +841,31 @@
                 }
 
                 var maskPos = pos;
-                if (maskPos >= getMaskLength()) { //try fuzzy alternator logic
-                    if (fromSetValid) {
-                        resetMaskSet(true);
-                        if (maskPos >= getMaskLength())
-                            return alternate(pos, c, strict, fromSetValid);
-                    } else
-                        return alternate(pos, c, strict, fromSetValid);
+                var result = false;
+
+                if (fromSetValid && maskPos >= getMaskLength()) {
+                    resetMaskSet(true); //masklenght can be altered on the process => reset to get the actual length
                 }
-                var result = _isValid(maskPos, c, strict, fromSetValid);
-                if (!strict && result === false) {
-                    var currentPosValid = getMaskSet()["validPositions"][maskPos];
-                    if (currentPosValid && currentPosValid["match"].fn == null && (currentPosValid["match"].def == c || c == opts.skipOptionalPartCharacter)) {
-                        result = { "caret": seekNext(maskPos) };
-                    } else if ((opts.insertMode || getMaskSet()["validPositions"][seekNext(maskPos)] == undefined) && !isMask(maskPos)) { //does the input match on a further position?
-                        for (var nPos = maskPos + 1, snPos = seekNext(maskPos) ; nPos <= snPos; nPos++) {
-                            result = _isValid(nPos, c, strict, fromSetValid);
-                            if (result !== false) {
-                                maskPos = nPos;
-                                break;
+                if (maskPos < getMaskLength()) {
+                    result = _isValid(maskPos, c, strict, fromSetValid);
+                    if (!strict && result === false) {
+                        var currentPosValid = getMaskSet()["validPositions"][maskPos];
+                        if (currentPosValid && currentPosValid["match"].fn == null && (currentPosValid["match"].def == c || c == opts.skipOptionalPartCharacter)) {
+                            result = { "caret": seekNext(maskPos) };
+                        } else if ((opts.insertMode || getMaskSet()["validPositions"][seekNext(maskPos)] == undefined) && !isMask(maskPos)) { //does the input match on a further position?
+                            for (var nPos = maskPos + 1, snPos = seekNext(maskPos) ; nPos <= snPos; nPos++) {
+                                result = _isValid(nPos, c, strict, fromSetValid);
+                                if (result !== false) {
+                                    maskPos = nPos;
+                                    break;
+                                }
                             }
                         }
                     }
                 }
-
+                if (result === false && opts.keepStatic && isComplete(buffer)) { //try fuzzy alternator logic
+                    result = alternate(pos, c, strict, fromSetValid);
+                }
                 if (result === true) result = { "pos": maskPos };
                 return result;
             }
@@ -1208,6 +1212,7 @@
             function handleRemove(input, k, pos) {
                 function generalize() {
                     if (opts.keepStatic) {
+                        resetMaskSet(true);
                         var validInputs = [],
                           lastAlt;
                         //find last alternation

+ 22 - 0
qunit/tests_keepStatic.js

@@ -58,4 +58,26 @@ test("{ mask: [\"+55-99-9999-9999\", \"+55-99-99999-9999\", ], keepStatic: true
     equal(document.getElementById("testmask")._valueGet(), "+55-12-1234-5123", "Result " + document.getElementById("testmask")._valueGet());
 
     $("#testmask").remove();
+});
+
+test("{ mask: [\"99-9999-99\",\"99-99999-99\"] } - type 12123412 + add 1 upfront", function () {
+    var $fixture = $("#qunit-fixture");
+    $fixture.append('<input type="text" id="testmask" />');
+    $("#testmask").inputmask({ mask: ["99-9999-99", "99-99999-99"] });
+    $("#testmask").Type("12123412");
+    $.caret($("#testmask"), 0);
+    $("#testmask").Type("1");
+    equal(document.getElementById("testmask")._valueGet(), "11-21234-12", "Result " + document.getElementById("testmask")._valueGet());
+
+    $("#testmask").remove();
+});
+
+test("{ mask: [\"99-99999-9\",\"99-999999-9\"] } - type 121234561", function () {
+    var $fixture = $("#qunit-fixture");
+    $fixture.append('<input type="text" id="testmask" />');
+    $("#testmask").inputmask({ mask: ["99-99999-9", "99-999999-9"] });
+    $("#testmask").Type("121234561");
+    equal(document.getElementById("testmask")._valueGet(), "12-123456-1", "Result " + document.getElementById("testmask")._valueGet());
+
+    $("#testmask").remove();
 });