ソースを参照

Merge branch '1.x' into 2.x

Robin Herbots 12 年 前
コミット
bf523a6eca

+ 1 - 1
build.properties

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

BIN
dist/jQuery.InputMask.1.3.8.nupkg


BIN
dist/jQuery.InputMask.2.1.6.nupkg


BIN
dist/jQuery.InputMask.2.1.7.nupkg


+ 123 - 81
dist/jquery.inputmask.bundle.js

@@ -3,7 +3,7 @@
 * http://github.com/RobinHerbots/jquery.inputmask
 * http://github.com/RobinHerbots/jquery.inputmask
 * Copyright (c) 2010 - 2013 Robin Herbots
 * Copyright (c) 2010 - 2013 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 2.1.6
+* Version: 2.1.7
 */
 */
 
 
 (function ($) {
 (function ($) {
@@ -57,19 +57,19 @@
                     NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91
                     NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91
                 },
                 },
                 //specify keycodes which should not be considered in the keypress event, otherwise the preventDefault will stop their default behavior especially in FF
                 //specify keycodes which should not be considered in the keypress event, otherwise the preventDefault will stop their default behavior especially in FF
-                ignorables: [9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123]
+                ignorables: [9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123],
+                getMaskLength: function (buffer, greedy, repeat, currentBuffer, opts) {
+                    var calculatedLength = buffer.length;
+                    if (!greedy && repeat > 1) {
+                        calculatedLength += (buffer.length * (repeat - 1));
+                    }
+                    return calculatedLength;
+                }
             },
             },
             val: $.fn.val, //store the original jquery val function
             val: $.fn.val, //store the original jquery val function
             escapeRegex: function (str) {
             escapeRegex: function (str) {
                 var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
                 var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
                 return str.replace(new RegExp('(\\' + specials.join('|\\') + ')', 'gim'), '\\$1');
                 return str.replace(new RegExp('(\\' + specials.join('|\\') + ')', 'gim'), '\\$1');
-            },
-            getMaskLength: function (buffer, greedy, repeat) {
-                var calculatedLength = buffer.length;
-                if (!greedy && repeat > 1) {
-                    calculatedLength += (buffer.length * (repeat - 1));
-                }
-                return calculatedLength;
             }
             }
         };
         };
 
 
@@ -156,7 +156,7 @@
                         masksets = this.data('inputmask')['masksets'];
                         masksets = this.data('inputmask')['masksets'];
                         activeMasksetIndex = this.data('inputmask')['activeMasksetIndex'];
                         activeMasksetIndex = this.data('inputmask')['activeMasksetIndex'];
                         opts.definitions = this.data('inputmask')['definitions'];
                         opts.definitions = this.data('inputmask')['definitions'];
-                        return isComplete(this[0]);
+                        return isComplete(this[0].split(''));
                     default:
                     default:
                         //check if the fn is an alias
                         //check if the fn is an alias
                         if (!resolveAlias(fn, options)) {
                         if (!resolveAlias(fn, options)) {
@@ -370,6 +370,7 @@
                     if (c) {
                     if (c) {
                         chrs += c;
                         chrs += c;
                     }
                     }
+
                     //return is false or a json object => { pos: ??, c: ??} or true
                     //return is false or a json object => { pos: ??, c: ??} or true
                     return activeMaskset['tests'][testPos].fn != null ? activeMaskset['tests'][testPos].fn.test(chrs, buffer, position, strict, opts) : false;
                     return activeMaskset['tests'][testPos].fn != null ? activeMaskset['tests'][testPos].fn.test(chrs, buffer, position, strict, opts) : false;
                 }
                 }
@@ -391,8 +392,8 @@
 
 
                         maskPos = isRTL ? seekPrevious(buffer, pos) : seekNext(buffer, pos);
                         maskPos = isRTL ? seekPrevious(buffer, pos) : seekNext(buffer, pos);
                     }
                     }
-                    if (isRTL ? activeMaskset['lastValidPosition'] <= opts.numericInput ? getMaskLength() : seekNext(buffer, maskPos) : activeMaskset['lastValidPosition'] >= seekPrevious(buffer, maskPos)) {
-                        if (maskPos >= 0 && maskPos < getMaskLength()) {
+                    if ((isRTL || opts.numericInput) ? activeMaskset['lastValidPosition'] <= opts.numericInput ? getMaskLength(buffer) : seekNext(buffer, maskPos) : activeMaskset['lastValidPosition'] >= seekPrevious(buffer, maskPos)) {
+                        if (maskPos >= 0 && maskPos < getMaskLength(buffer)) {
                             results[index] = _isValid(maskPos, activeMaskset);
                             results[index] = _isValid(maskPos, activeMaskset);
                             if (results[index] !== false) {
                             if (results[index] !== false) {
                                 if (results[index] === true) {
                                 if (results[index] === true) {
@@ -413,12 +414,12 @@
             function determineActiveMasksetIndex(buffer, pos, currentActiveMasksetIndex, isRTL) {
             function determineActiveMasksetIndex(buffer, pos, currentActiveMasksetIndex, isRTL) {
                 $.each(masksets, function (index, value) {
                 $.each(masksets, function (index, value) {
                     var activeMaskset = this;
                     var activeMaskset = this;
-                    if (isRTL ? activeMaskset['lastValidPosition'] <= pos : activeMaskset['lastValidPosition'] >= pos) {
+                    if ((isRTL || opts.numericInput) ? activeMaskset['lastValidPosition'] <= pos : activeMaskset['lastValidPosition'] >= pos) {
                         activeMasksetIndex = index;
                         activeMasksetIndex = index;
                         //reset to correct masktemplate
                         //reset to correct masktemplate
                         if (activeMasksetIndex != currentActiveMasksetIndex) {
                         if (activeMasksetIndex != currentActiveMasksetIndex) {
-                            var abl = getMaskLength(), bufTemplate = getActiveBuffer();
-                            if (isRTL) {
+                            var abl = getMaskLength(buffer), bufTemplate = getActiveBuffer();
+                            if (isRTL || opts.numericInput) {
                                 buffer.reverse();
                                 buffer.reverse();
                                 bufTemplate.reverse();
                                 bufTemplate.reverse();
                             }
                             }
@@ -451,13 +452,13 @@
                 return opts.placeholder.charAt(pos % opts.placeholder.length);
                 return opts.placeholder.charAt(pos % opts.placeholder.length);
             }
             }
 
 
-            function getMaskLength() {
-                return $.inputmask.getMaskLength(getActiveBuffer(), getActiveMaskSet()['greedy'], getActiveMaskSet()['repeat']);
+            function getMaskLength(currentBuffer) {
+                return opts.getMaskLength(getActiveBuffer(), getActiveMaskSet()['greedy'], getActiveMaskSet()['repeat'], currentBuffer, opts);
             }
             }
 
 
             //pos: from position
             //pos: from position
             function seekNext(buffer, pos) {
             function seekNext(buffer, pos) {
-                var maskL = getMaskLength();
+                var maskL = getMaskLength(buffer);
                 if (pos >= maskL) return maskL;
                 if (pos >= maskL) return maskL;
                 var position = pos;
                 var position = pos;
                 while (++position < maskL && !isMask(position)) { };
                 while (++position < maskL && !isMask(position)) { };
@@ -499,7 +500,7 @@
             function prepareBuffer(buffer, position, isRTL) {
             function prepareBuffer(buffer, position, isRTL) {
                 var j;
                 var j;
                 if (isRTL) {
                 if (isRTL) {
-                    while (position < 0 && buffer.length < getMaskLength()) {
+                    while (position < 0 && buffer.length < getMaskLength(buffer)) {
                         j = getActiveBuffer().length - 1;
                         j = getActiveBuffer().length - 1;
                         position = getActiveBuffer().length;
                         position = getActiveBuffer().length;
                         while (getActiveBuffer()[j] !== undefined) {
                         while (getActiveBuffer()[j] !== undefined) {
@@ -507,7 +508,7 @@
                         }
                         }
                     }
                     }
                 } else {
                 } else {
-                    while (buffer[position] == undefined && buffer.length < getMaskLength()) {
+                    while (buffer[position] == undefined && buffer.length < getMaskLength(buffer)) {
                         j = 0;
                         j = 0;
                         while (getActiveBuffer()[j] !== undefined) { //add a new buffer
                         while (getActiveBuffer()[j] !== undefined) { //add a new buffer
                             buffer.push(getActiveBuffer()[j++]);
                             buffer.push(getActiveBuffer()[j++]);
@@ -530,7 +531,7 @@
                 }
                 }
             };
             };
             function clearBuffer(buffer, start, end) {
             function clearBuffer(buffer, start, end) {
-                for (var i = start, maskL = getMaskLength() ; i < end && i < maskL; i++) {
+                for (var i = start, maskL = getMaskLength(buffer) ; i < end && i < maskL; i++) {
                     setBufferElement(buffer, i, getBufferElement(getActiveBuffer().slice(), i));
                     setBufferElement(buffer, i, getBufferElement(getActiveBuffer().slice(), i));
                 }
                 }
             };
             };
@@ -544,8 +545,8 @@
                 var isRTL = $(input).data('inputmask')['isRTL'],
                 var isRTL = $(input).data('inputmask')['isRTL'],
                     inputValue = truncateInput(input._valueGet(), isRTL).split('');
                     inputValue = truncateInput(input._valueGet(), isRTL).split('');
 
 
+                var maskL = getMaskLength(buffer);
                 if (isRTL) { //align inputValue for RTL/numeric input
                 if (isRTL) { //align inputValue for RTL/numeric input
-                    var maskL = getMaskLength();
                     var inputValueRev = inputValue.reverse(); inputValueRev.length = maskL;
                     var inputValueRev = inputValue.reverse(); inputValueRev.length = maskL;
 
 
                     for (var i = 0; i < maskL; i++) {
                     for (var i = 0; i < maskL; i++) {
@@ -561,7 +562,7 @@
                 }
                 }
                 clearBuffer(buffer, 0, buffer.length);
                 clearBuffer(buffer, 0, buffer.length);
                 buffer.length = getActiveBuffer().length;
                 buffer.length = getActiveBuffer().length;
-                var lastMatch = -1, checkPosition = -1, np, maskL = getMaskLength(), ivl = inputValue.length, rtlMatch = ivl == 0 ? maskL : -1;
+                var lastMatch = -1, checkPosition = -1, np, ivl = inputValue.length, rtlMatch = ivl == 0 ? maskL : -1;
                 for (var i = 0; i < ivl; i++) {
                 for (var i = 0; i < ivl; i++) {
                     for (var pos = checkPosition + 1; pos < maskL; pos++) {
                     for (var pos = checkPosition + 1; pos < maskL; pos++) {
                         if (isMask(pos)) {
                         if (isMask(pos)) {
@@ -689,17 +690,17 @@
                 }
                 }
             };
             };
 
 
-            function isComplete(npt) {
-                var complete = false, nptValue = npt._valueGet(), ml = nptValue.length
+            function isComplete(buffer) {
+                var complete = false;
                 currentActiveMasksetIndex = activeMasksetIndex, highestValidPosition = 0;
                 currentActiveMasksetIndex = activeMasksetIndex, highestValidPosition = 0;
                 $.each(masksets, function (ndx, ms) {
                 $.each(masksets, function (ndx, ms) {
                     activeMasksetIndex = ndx;
                     activeMasksetIndex = ndx;
-                    var aml = getMaskLength();
+                    var aml = getMaskLength(buffer);
                     if (ms["lastValidPosition"] >= highestValidPosition && ms["lastValidPosition"] == (aml - 1)) {
                     if (ms["lastValidPosition"] >= highestValidPosition && ms["lastValidPosition"] == (aml - 1)) {
                         var msComplete = true;
                         var msComplete = true;
                         for (var i = 0; i < aml; i++) {
                         for (var i = 0; i < aml; i++) {
                             var mask = isMask(i);
                             var mask = isMask(i);
-                            if ((mask && nptValue.charAt(i) == getPlaceHolder(i)) || (!mask && nptValue.charAt(i) != getActiveBuffer()[i])) {
+                            if ((mask && buffer[i] == getPlaceHolder(i)) || (!mask && buffer[i] != getActiveBuffer()[i])) {
                                 msComplete = false;
                                 msComplete = false;
                                 break;
                                 break;
                             }
                             }
@@ -718,19 +719,19 @@
                 var $input = $(el);
                 var $input = $(el);
                 if (!$input.is(":input")) return;
                 if (!$input.is(":input")) return;
 
 
+                var buffer = getActiveBuffer().slice();
+
                 //correct greedy setting if needed
                 //correct greedy setting if needed
                 getActiveMaskSet()['greedy'] = getActiveMaskSet()['greedy'] ? getActiveMaskSet()['greedy'] : getActiveMaskSet()['repeat'] == 0;
                 getActiveMaskSet()['greedy'] = getActiveMaskSet()['greedy'] ? getActiveMaskSet()['greedy'] : getActiveMaskSet()['repeat'] == 0;
 
 
-
-
                 //handle maxlength attribute
                 //handle maxlength attribute
                 var maxLength = $input.prop('maxLength');
                 var maxLength = $input.prop('maxLength');
-                if (getMaskLength() > maxLength && maxLength > -1) { //FF sets no defined max length to -1 
+                if (getMaskLength(buffer) > maxLength && maxLength > -1) { //FF sets no defined max length to -1 
                     if (maxLength < getActiveBuffer().length) getActiveBuffer().length = maxLength;
                     if (maxLength < getActiveBuffer().length) getActiveBuffer().length = maxLength;
                     if (getActiveMaskSet()['greedy'] == false) {
                     if (getActiveMaskSet()['greedy'] == false) {
                         getActiveMaskSet()['repeat'] = Math.round(maxLength / getActiveBuffer().length);
                         getActiveMaskSet()['repeat'] = Math.round(maxLength / getActiveBuffer().length);
                     }
                     }
-                    $input.prop('maxLength', getMaskLength() * 2);
+                    $input.prop('maxLength', getMaskLength(buffer) * 2);
                 }
                 }
 
 
                 //store tests & original buffer in the input element - used to get the unmasked value
                 //store tests & original buffer in the input element - used to get the unmasked value
@@ -747,11 +748,12 @@
                 //init vars
                 //init vars
                 var buffer = getActiveBuffer().slice(),
                 var buffer = getActiveBuffer().slice(),
                 undoBuffer = el._valueGet(),
                 undoBuffer = el._valueGet(),
+
                 skipKeyPressEvent = false, //Safari 5.1.x - modal dialog fires keypress twice workaround
                 skipKeyPressEvent = false, //Safari 5.1.x - modal dialog fires keypress twice workaround
                 ignorable = false,
                 ignorable = false,
                 lastPosition = -1,
                 lastPosition = -1,
                 firstMaskPos = seekNext(buffer, -1),
                 firstMaskPos = seekNext(buffer, -1),
-                lastMaskPos = seekPrevious(buffer, getMaskLength()),
+                lastMaskPos = seekPrevious(buffer, getMaskLength(buffer)),
                 isRTL = false;
                 isRTL = false;
                 if (el.dir == "rtl" || opts.numericInput) {
                 if (el.dir == "rtl" || opts.numericInput) {
                     el.dir = "ltr"
                     el.dir = "ltr"
@@ -790,7 +792,7 @@
                             clearOptionalTail(input, buffer);
                             clearOptionalTail(input, buffer);
                         }
                         }
                     }
                     }
-                    if (!isComplete(input)) {
+                    if (!isComplete(buffer)) {
                         $input.trigger("incomplete");
                         $input.trigger("incomplete");
                         if (opts.clearIncomplete) {
                         if (opts.clearIncomplete) {
                             if (opts.clearMaskOnLostFocus)
                             if (opts.clearMaskOnLostFocus)
@@ -831,6 +833,7 @@
                         if (selectedCaret.begin == selectedCaret.end) {
                         if (selectedCaret.begin == selectedCaret.end) {
                             var clickPosition = selectedCaret.begin;
                             var clickPosition = selectedCaret.begin;
                             lastPosition = checkVal(input, buffer, false);
                             lastPosition = checkVal(input, buffer, false);
+                            determineInputDirection(input, selectedCaret);
                             if (isRTL)
                             if (isRTL)
                                 caret(input, clickPosition > lastPosition && (isValid(clickPosition, buffer[clickPosition], buffer, true, isRTL) !== false || !isMask(clickPosition)) ? clickPosition : lastPosition);
                                 caret(input, clickPosition > lastPosition && (isValid(clickPosition, buffer[clickPosition], buffer, true, isRTL) !== false || !isMask(clickPosition)) ? clickPosition : lastPosition);
                             else
                             else
@@ -849,7 +852,7 @@
                     var input = this;
                     var input = this;
                     setTimeout(function () {
                     setTimeout(function () {
                         caret(input, checkVal(input, buffer, true));
                         caret(input, checkVal(input, buffer, true));
-                        if (isComplete(input))
+                        if (isComplete(buffer))
                             $input.trigger("complete");
                             $input.trigger("complete");
                     }, 0);
                     }, 0);
                 }).bind('setvalue.inputmask', function () {
                 }).bind('setvalue.inputmask', function () {
@@ -971,16 +974,26 @@
                         }
                         }
                     }
                     }
                 }
                 }
+
+                function determineInputDirection(input, pos) {
+                    //set input direction according the position to the radixPoint
+                    if (opts.numericInput && opts.radixPoint != "") {
+                        var nptStr = input._valueGet();
+                        var radixPosition = nptStr.indexOf(opts.radixPoint);
+                        isRTL = pos.begin <= radixPosition || pos.end <= radixPosition || radixPosition == -1;
+                    }
+                }
+
                 //shift chars to left from start to end and put c at end position if defined
                 //shift chars to left from start to end and put c at end position if defined
                 function shiftL(start, end, c) {
                 function shiftL(start, end, c) {
                     while (!isMask(start) && start - 1 >= 0) start--;
                     while (!isMask(start) && start - 1 >= 0) start--;
-                    for (var i = start; i < end && i < getMaskLength() ; i++) {
+                    for (var i = start; i < end && i < getMaskLength(buffer) ; i++) {
                         if (isMask(i)) {
                         if (isMask(i)) {
                             setReTargetPlaceHolder(buffer, i);
                             setReTargetPlaceHolder(buffer, i);
                             var j = seekNext(buffer, i);
                             var j = seekNext(buffer, i);
                             var p = getBufferElement(buffer, j);
                             var p = getBufferElement(buffer, j);
                             if (p != getPlaceHolder(j)) {
                             if (p != getPlaceHolder(j)) {
-                                if (j < getMaskLength() && isValid(i, p, buffer, true, isRTL) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def) {
+                                if (j < getMaskLength(buffer) && isValid(i, p, buffer, true, isRTL) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def) {
                                     setBufferElement(buffer, i, getBufferElement(buffer, j));
                                     setBufferElement(buffer, i, getBufferElement(buffer, j));
                                     setReTargetPlaceHolder(buffer, j); //cleanup next position
                                     setReTargetPlaceHolder(buffer, j); //cleanup next position
                                 } else {
                                 } else {
@@ -1001,13 +1014,13 @@
                     return start; //return the used start position
                     return start; //return the used start position
                 }
                 }
                 function shiftR(start, end, c, full) { //full => behave like a push right ~ do not stop on placeholders
                 function shiftR(start, end, c, full) { //full => behave like a push right ~ do not stop on placeholders
-                    for (var i = start; i <= end && i < getMaskLength() ; i++) {
+                    for (var i = start; i <= end && i < getMaskLength(buffer) ; i++) {
                         if (isMask(i)) {
                         if (isMask(i)) {
                             var t = getBufferElement(buffer, i);
                             var t = getBufferElement(buffer, i);
                             setBufferElement(buffer, i, c);
                             setBufferElement(buffer, i, c);
                             if (t != getPlaceHolder(i)) {
                             if (t != getPlaceHolder(i)) {
                                 var j = seekNext(buffer, i);
                                 var j = seekNext(buffer, i);
-                                if (j < getMaskLength()) {
+                                if (j < getMaskLength(buffer)) {
                                     if (isValid(j, t, buffer, true, isRTL) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def)
                                     if (isValid(j, t, buffer, true, isRTL) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def)
                                         c = t;
                                         c = t;
                                     else {
                                     else {
@@ -1033,47 +1046,58 @@
 
 
                     var input = this, k = e.keyCode, pos = caret(input);
                     var input = this, k = e.keyCode, pos = caret(input);
 
 
-                    //set input direction according the position to the radixPoint
-                    if (opts.numericInput && opts.radixPoint != "") {
-                        var nptStr = input._valueGet();
-                        var radixPosition = nptStr.indexOf(opts.radixPoint);
-                        if (radixPosition != -1) {
-                            isRTL = pos.begin <= radixPosition || pos.end <= radixPosition;
-                        }
-                    }
+                    determineInputDirection(input, pos);
 
 
                     //backspace, delete, and escape get special treatment
                     //backspace, delete, and escape get special treatment
                     if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iphone && k == 127)) {//backspace/delete
                     if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iphone && k == 127)) {//backspace/delete
-                        var maskL = getMaskLength();
-                        if (pos.begin == 0 && pos.end == maskL) {
+                        var maskL = getMaskLength(buffer);
+                        if (pos.begin == 0 && pos.end == maskL) { //remove full selection
                             activeMasksetIndex = 0; //reset activemask
                             activeMasksetIndex = 0; //reset activemask
                             buffer = getActiveBuffer().slice();
                             buffer = getActiveBuffer().slice();
                             writeBuffer(input, buffer);
                             writeBuffer(input, buffer);
                             caret(input, checkVal(input, buffer, false));
                             caret(input, checkVal(input, buffer, false));
-                        } else if ((pos.end - pos.begin) > 1 || ((pos.end - pos.begin) == 1 && opts.insertMode)) {
+                        } else if ((pos.end - pos.begin) > 1 || ((pos.end - pos.begin) == 1 && opts.insertMode)) { //partial selection
                             clearBuffer(buffer, pos.begin, pos.end);
                             clearBuffer(buffer, pos.begin, pos.end);
                             determineActiveMasksetIndex(buffer, pos.begin, activeMasksetIndex);
                             determineActiveMasksetIndex(buffer, pos.begin, activeMasksetIndex);
                             writeBuffer(input, buffer);
                             writeBuffer(input, buffer);
                             caret(isRTL ? checkVal(input, buffer, false) : pos.begin);
                             caret(isRTL ? checkVal(input, buffer, false) : pos.begin);
-                        } else {
-                            var beginPos = pos.begin - (k == opts.keyCode.DELETE ? 0 : 1);
-                            if (beginPos < firstMaskPos && k == opts.keyCode.DELETE) {
-                                beginPos = firstMaskPos;
-                            }
-                            if (beginPos >= firstMaskPos) {
-                                if (opts.numericInput && getActiveMaskSet()['greedy'] && k == opts.keyCode.DELETE && buffer[beginPos] == opts.radixPoint) {
-                                    beginPos = seekNext(buffer, beginPos);
-                                    isRTL = false;
-                                } else if (opts.numericInput && getActiveMaskSet()['greedy'] && k == opts.keyCode.BACKSPACE && buffer[beginPos] == opts.radixPoint) {
-                                    beginPos--;
-                                    isRTL = true;
+                        } else { //handle delete
+                            var beginPos = pos.begin;
+                            if (k == opts.keyCode.DELETE) {
+                                if (beginPos < firstMaskPos)
+                                    beginPos = firstMaskPos;
+                                if (beginPos < maskL) {
+                                    if (opts.numericInput && opts.radixPoint != "" && buffer[beginPos] == opts.radixPoint) {
+                                        beginPos = (buffer.length - 1 == beginPos) /* radixPoint is latest? delete it */ ? beginPos : seekNext(buffer, beginPos);
+                                        beginPos = shiftL(beginPos, maskL);
+                                    } else {
+                                        if (isRTL) {
+                                            beginPos = shiftR(firstMaskPos, beginPos, getPlaceHolder(beginPos), true);
+                                            beginPos = seekNext(buffer, beginPos);
+                                        } else {
+                                            beginPos = shiftL(beginPos, maskL);
+                                        }
+                                    }
+                                    determineActiveMasksetIndex(buffer, beginPos, activeMasksetIndex);
+                                    writeBuffer(input, buffer, beginPos);
+                                }
+                            } else if (k == opts.keyCode.BACKSPACE) { //handle backspace
+                                if (beginPos > firstMaskPos) {
+                                    beginPos -= 1;
+                                    if (opts.numericInput && opts.radixPoint != "" && buffer[beginPos] == opts.radixPoint) {
+                                        beginPos = shiftR(firstMaskPos, (buffer.length - 1 == beginPos) /* radixPoint is latest? delete it */ ? beginPos : beginPos - 1, getPlaceHolder(beginPos), true);
+                                        beginPos++;
+                                    } else {
+                                        if (isRTL) {
+                                            beginPos = shiftR(firstMaskPos, beginPos, getPlaceHolder(beginPos), true);
+                                            beginPos = buffer[beginPos + 1] == opts.radixPoint ? beginPos + 1 : seekNext(buffer, beginPos);
+                                        } else {
+                                            beginPos = shiftL(beginPos, maskL);
+                                        }
+                                    }
+                                    determineActiveMasksetIndex(buffer, beginPos, activeMasksetIndex);
+                                    writeBuffer(input, buffer, beginPos);
                                 }
                                 }
-                                if (isRTL) {
-                                    beginPos = shiftR(firstMaskPos, beginPos, getPlaceHolder(beginPos), true);
-                                    beginPos = (opts.numericInput && getActiveMaskSet()['greedy'] && k == opts.keyCode.BACKSPACE && buffer[beginPos + 1] == opts.radixPoint) ? beginPos + 1 : seekNext(buffer, beginPos);
-                                } else beginPos = shiftL(beginPos, maskL);
-                                determineActiveMasksetIndex(buffer, beginPos, activeMasksetIndex);
-                                writeBuffer(input, buffer, beginPos);
                             }
                             }
                         }
                         }
                         if (input._valueGet() == getActiveBuffer().join(''))
                         if (input._valueGet() == getActiveBuffer().join(''))
@@ -1083,7 +1107,7 @@
                     } else if (k == opts.keyCode.END || k == opts.keyCode.PAGE_DOWN) { //when END or PAGE_DOWN pressed set position at lastmatch
                     } else if (k == opts.keyCode.END || k == opts.keyCode.PAGE_DOWN) { //when END or PAGE_DOWN pressed set position at lastmatch
                         setTimeout(function () {
                         setTimeout(function () {
                             var caretPos = checkVal(input, buffer, false, true);
                             var caretPos = checkVal(input, buffer, false, true);
-                            if (!opts.insertMode && caretPos == getMaskLength() && !e.shiftKey) caretPos--;
+                            if (!opts.insertMode && caretPos == getMaskLength(buffer) && !e.shiftKey) caretPos--;
                             caret(input, e.shiftKey ? pos.begin : caretPos, caretPos);
                             caret(input, e.shiftKey ? pos.begin : caretPos, caretPos);
                         }, 0);
                         }, 0);
                     } else if (k == opts.keyCode.HOME || k == opts.keyCode.PAGE_UP) {//Home or page_up
                     } else if (k == opts.keyCode.HOME || k == opts.keyCode.PAGE_UP) {//Home or page_up
@@ -1094,7 +1118,7 @@
                         caret(input, 0, checkVal(input, buffer));
                         caret(input, 0, checkVal(input, buffer));
                     } else if (k == opts.keyCode.INSERT) {//insert
                     } else if (k == opts.keyCode.INSERT) {//insert
                         opts.insertMode = !opts.insertMode;
                         opts.insertMode = !opts.insertMode;
-                        caret(input, !opts.insertMode && pos.begin == getMaskLength() ? pos.begin - 1 : pos.begin);
+                        caret(input, !opts.insertMode && pos.begin == getMaskLength(buffer) ? pos.begin - 1 : pos.begin);
                     } else if (e.ctrlKey && k == 88) {
                     } else if (e.ctrlKey && k == 88) {
                         setTimeout(function () {
                         setTimeout(function () {
                             caret(input, checkVal(input, buffer, true));
                             caret(input, checkVal(input, buffer, true));
@@ -1102,7 +1126,7 @@
                     } else if (!opts.insertMode) { //overwritemode
                     } else if (!opts.insertMode) { //overwritemode
                         if (k == opts.keyCode.RIGHT) {//right
                         if (k == opts.keyCode.RIGHT) {//right
                             var caretPos = pos.begin == pos.end ? pos.end + 1 : pos.end;
                             var caretPos = pos.begin == pos.end ? pos.end + 1 : pos.end;
-                            caretPos = caretPos < getMaskLength() ? caretPos : pos.end;
+                            caretPos = caretPos < getMaskLength(buffer) ? caretPos : pos.end;
                             caret(input, e.shiftKey ? pos.begin : caretPos, e.shiftKey ? caretPos + 1 : caretPos);
                             caret(input, e.shiftKey ? pos.begin : caretPos, e.shiftKey ? caretPos + 1 : caretPos);
                         } else if (k == opts.keyCode.LEFT) {//left
                         } else if (k == opts.keyCode.LEFT) {//left
                             var caretPos = pos.begin - 1;
                             var caretPos = pos.begin - 1;
@@ -1129,7 +1153,7 @@
                     if (opts.numericInput && c == opts.radixPoint) {
                     if (opts.numericInput && c == opts.radixPoint) {
                         var nptStr = input._valueGet();
                         var nptStr = input._valueGet();
                         var radixPosition = nptStr.indexOf(opts.radixPoint);
                         var radixPosition = nptStr.indexOf(opts.radixPoint);
-                        caret(input, seekNext(buffer, radixPosition != -1 ? radixPosition : getMaskLength()));
+                        caret(input, seekNext(buffer, radixPosition != -1 ? radixPosition : getMaskLength(buffer)));
                     }
                     }
 
 
                     if (e.ctrlKey || e.altKey || e.metaKey || ignorable) {
                     if (e.ctrlKey || e.altKey || e.metaKey || ignorable) {
@@ -1138,7 +1162,7 @@
                         if (k) {
                         if (k) {
                             $input.trigger('input');
                             $input.trigger('input');
 
 
-                            var pos = caret(input), maskL = getMaskLength(), writeOutBuffer = true;
+                            var pos = caret(input), maskL = getMaskLength(buffer), writeOutBuffer = true;
                             clearBuffer(buffer, pos.begin, pos.end);
                             clearBuffer(buffer, pos.begin, pos.end);
 
 
                             if (isRTL) {
                             if (isRTL) {
@@ -1151,6 +1175,7 @@
                                         c = np.c != undefined ? np.c : c; //set new char from isValid
                                         c = np.c != undefined ? np.c : c; //set new char from isValid
                                     }
                                     }
                                     if (refresh !== true) {
                                     if (refresh !== true) {
+                                        maskL = getMaskLength(buffer); //update masklength to include possible groupSeparator offset
                                         var firstUnmaskedPosition = firstMaskPos;
                                         var firstUnmaskedPosition = firstMaskPos;
                                         if (opts.insertMode == true) {
                                         if (opts.insertMode == true) {
                                             if (getActiveMaskSet()['greedy'] == true) {
                                             if (getActiveMaskSet()['greedy'] == true) {
@@ -1173,7 +1198,7 @@
                                     if (writeOutBuffer) {
                                     if (writeOutBuffer) {
                                         writeBuffer(input, buffer, opts.numericInput ? p + 1 : p);
                                         writeBuffer(input, buffer, opts.numericInput ? p + 1 : p);
                                         setTimeout(function () { //timeout needed for IE
                                         setTimeout(function () { //timeout needed for IE
-                                            if (isComplete(input))
+                                            if (isComplete(buffer))
                                                 $input.trigger("complete");
                                                 $input.trigger("complete");
                                         }, 0);
                                         }, 0);
                                     }
                                     }
@@ -1191,7 +1216,7 @@
                                     }
                                     }
                                     if (refresh !== true) {
                                     if (refresh !== true) {
                                         if (opts.insertMode == true) {
                                         if (opts.insertMode == true) {
-                                            var lastUnmaskedPosition = getMaskLength();
+                                            var lastUnmaskedPosition = getMaskLength(buffer);
                                             var bfrClone = buffer.slice();
                                             var bfrClone = buffer.slice();
                                             while (getBufferElement(bfrClone, lastUnmaskedPosition, true) != getPlaceHolder(lastUnmaskedPosition) && lastUnmaskedPosition >= p) {
                                             while (getBufferElement(bfrClone, lastUnmaskedPosition, true) != getPlaceHolder(lastUnmaskedPosition) && lastUnmaskedPosition >= p) {
                                                 lastUnmaskedPosition = lastUnmaskedPosition == 0 ? -1 : seekPrevious(buffer, lastUnmaskedPosition);
                                                 lastUnmaskedPosition = lastUnmaskedPosition == 0 ? -1 : seekPrevious(buffer, lastUnmaskedPosition);
@@ -1206,7 +1231,7 @@
                                         writeBuffer(input, buffer, next);
                                         writeBuffer(input, buffer, next);
 
 
                                         setTimeout(function () { //timeout needed for IE
                                         setTimeout(function () { //timeout needed for IE
-                                            if (isComplete(input))
+                                            if (isComplete(buffer))
                                                 $input.trigger("complete");
                                                 $input.trigger("complete");
                                         }, 0);
                                         }, 0);
                                     }
                                     }
@@ -1239,7 +1264,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2013 Robin Herbots
 Copyright (c) 2010 - 2013 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 2.1.6
+Version: 2.1.7
 
 
 Optional extensions on the jquery.inputmask base
 Optional extensions on the jquery.inputmask base
 */
 */
@@ -1336,7 +1361,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2012 Robin Herbots
 Copyright (c) 2010 - 2012 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 2.1.6
+Version: 2.1.7
 
 
 Optional extensions on the jquery.inputmask base
 Optional extensions on the jquery.inputmask base
 */
 */
@@ -1829,7 +1854,7 @@ Input Mask plugin extensions
 http://github.com/RobinHerbots/jquery.inputmask
 http://github.com/RobinHerbots/jquery.inputmask
 Copyright (c) 2010 - 2013 Robin Herbots
 Copyright (c) 2010 - 2013 Robin Herbots
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
 Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-Version: 2.1.6
+Version: 2.1.7
 
 
 Optional extensions on the jquery.inputmask base
 Optional extensions on the jquery.inputmask base
 */
 */
@@ -1847,17 +1872,34 @@ Optional extensions on the jquery.inputmask base
             radixPoint: ".",
             radixPoint: ".",
             groupSize: 3,
             groupSize: 3,
             autoGroup: false,
             autoGroup: false,
+            getMaskLength: function (buffer, greedy, repeat, currentBuffer, opts) { //custom getMaskLength to take the groupSeparator into account
+                var calculatedLength = buffer.length;
+
+                if (!greedy && repeat > 1) {
+                    calculatedLength += (buffer.length * (repeat - 1));
+                }
+
+                var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);
+                var escapedRadixPoint = $.inputmask.escapeRegex.call(this, opts.radixPoint);
+                var currentBufferStr = currentBuffer.join(''), strippedBufferStr = currentBufferStr.replace(new RegExp(escapedGroupSeparator, "g"), "").replace(new RegExp(escapedRadixPoint), ""),
+                groupOffset = currentBufferStr.length - strippedBufferStr.length;
+                return calculatedLength + groupOffset;
+            },
             postFormat: function (buffer, pos, reformatOnly, opts) {
             postFormat: function (buffer, pos, reformatOnly, opts) {
                 var cbuf = buffer.slice();
                 var cbuf = buffer.slice();
                 if (!reformatOnly) cbuf.splice(pos, 0, "?"); //set position indicator
                 if (!reformatOnly) cbuf.splice(pos, 0, "?"); //set position indicator
                 var bufVal = cbuf.join('');
                 var bufVal = cbuf.join('');
                 if (opts.autoGroup || (reformatOnly && bufVal.indexOf(opts.groupSeparator) != -1)) {
                 if (opts.autoGroup || (reformatOnly && bufVal.indexOf(opts.groupSeparator) != -1)) {
                     bufVal = bufVal.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                     bufVal = bufVal.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
+                    var radixSplit = bufVal.split(opts.radixPoint);
+                    bufVal = radixSplit[0];
                     var reg = new RegExp('([-\+]?[\\d\?]+)([\\d\?]{' + opts.groupSize + '})');
                     var reg = new RegExp('([-\+]?[\\d\?]+)([\\d\?]{' + opts.groupSize + '})');
                     while (reg.test(bufVal)) {
                     while (reg.test(bufVal)) {
                         bufVal = bufVal.replace(reg, '$1' + opts.groupSeparator + '$2');
                         bufVal = bufVal.replace(reg, '$1' + opts.groupSeparator + '$2');
                         bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator);
                         bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator);
                     }
                     }
+                    if (radixSplit.length > 1)
+                        bufVal += opts.radixPoint + radixSplit[1];
                 }
                 }
                 buffer.length = bufVal.length; //align the length
                 buffer.length = bufVal.length; //align the length
                 for (var i = 0, l = bufVal.length; i < l; i++) {
                 for (var i = 0, l = bufVal.length; i < l; i++) {
@@ -1907,7 +1949,7 @@ Optional extensions on the jquery.inputmask base
 
 
                         cbuf.splice(pos + 1, 0, chrs);
                         cbuf.splice(pos + 1, 0, chrs);
                         var bufferStr = cbuf.join('');
                         var bufferStr = cbuf.join('');
-                        if (opts.autoGroup) //strip groupseparator
+                        if (opts.autoGroup && !strict) //strip groupseparator
                             bufferStr = bufferStr.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                             bufferStr = bufferStr.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                         var isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                         var isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                         if (!isValid) {
                         if (!isValid) {
@@ -1935,7 +1977,7 @@ Optional extensions on the jquery.inputmask base
                             }
                             }
                         }
                         }
 
 
-                        if (isValid != false && !strict) {
+                        if (isValid != false && !strict && chrs != opts.radixPoint) {
                             var newPos = opts.postFormat(buffer, pos + 1, false, opts);
                             var newPos = opts.postFormat(buffer, pos + 1, false, opts);
                             return { "pos": newPos };
                             return { "pos": newPos };
                         }
                         }
@@ -1966,4 +2008,4 @@ Optional extensions on the jquery.inputmask base
             alias: "decimal"
             alias: "decimal"
         }
         }
     });
     });
-})(jQuery);
+})(jQuery);

ファイルの差分が大きいため隠しています
+ 58 - 57
dist/jquery.inputmask.bundle.min.js


ファイルの差分が大きいため隠しています
+ 37 - 37
dist/min/jquery.inputmask.js


ファイルの差分が大きいため隠しています
+ 6 - 5
dist/min/jquery.inputmask.numeric.extensions.js


+ 5 - 1
jquery.inputmask.jquery.json

@@ -8,7 +8,11 @@
 		"inputmask",
 		"inputmask",
 		"mask"
 		"mask"
     ],
     ],
-    "version": "2.1.6"
+<<<<<<< HEAD
+    "version": "2.1.7"
+=======
+    "version": "2.1.7"
+>>>>>>> 1.x
     "author": {
     "author": {
         "name": "Robin Herbots",
         "name": "Robin Herbots",
         "url": "http://github.com/RobinHerbots/jquery.inputmask"
         "url": "http://github.com/RobinHerbots/jquery.inputmask"

+ 99 - 74
js/jquery.inputmask.js

@@ -57,19 +57,19 @@
                     NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91
                     NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91
                 },
                 },
                 //specify keycodes which should not be considered in the keypress event, otherwise the preventDefault will stop their default behavior especially in FF
                 //specify keycodes which should not be considered in the keypress event, otherwise the preventDefault will stop their default behavior especially in FF
-                ignorables: [9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123]
+                ignorables: [9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123],
+                getMaskLength: function (buffer, greedy, repeat, currentBuffer, opts) {
+                    var calculatedLength = buffer.length;
+                    if (!greedy && repeat > 1) {
+                        calculatedLength += (buffer.length * (repeat - 1));
+                    }
+                    return calculatedLength;
+                }
             },
             },
             val: $.fn.val, //store the original jquery val function
             val: $.fn.val, //store the original jquery val function
             escapeRegex: function (str) {
             escapeRegex: function (str) {
                 var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
                 var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
                 return str.replace(new RegExp('(\\' + specials.join('|\\') + ')', 'gim'), '\\$1');
                 return str.replace(new RegExp('(\\' + specials.join('|\\') + ')', 'gim'), '\\$1');
-            },
-            getMaskLength: function (buffer, greedy, repeat) {
-                var calculatedLength = buffer.length;
-                if (!greedy && repeat > 1) {
-                    calculatedLength += (buffer.length * (repeat - 1));
-                }
-                return calculatedLength;
             }
             }
         };
         };
 
 
@@ -156,7 +156,7 @@
                         masksets = this.data('inputmask')['masksets'];
                         masksets = this.data('inputmask')['masksets'];
                         activeMasksetIndex = this.data('inputmask')['activeMasksetIndex'];
                         activeMasksetIndex = this.data('inputmask')['activeMasksetIndex'];
                         opts.definitions = this.data('inputmask')['definitions'];
                         opts.definitions = this.data('inputmask')['definitions'];
-                        return isComplete(this[0]);
+                        return isComplete(this[0].split(''));
                     default:
                     default:
                         //check if the fn is an alias
                         //check if the fn is an alias
                         if (!resolveAlias(fn, options)) {
                         if (!resolveAlias(fn, options)) {
@@ -370,6 +370,7 @@
                     if (c) {
                     if (c) {
                         chrs += c;
                         chrs += c;
                     }
                     }
+
                     //return is false or a json object => { pos: ??, c: ??} or true
                     //return is false or a json object => { pos: ??, c: ??} or true
                     return activeMaskset['tests'][testPos].fn != null ? activeMaskset['tests'][testPos].fn.test(chrs, buffer, position, strict, opts) : false;
                     return activeMaskset['tests'][testPos].fn != null ? activeMaskset['tests'][testPos].fn.test(chrs, buffer, position, strict, opts) : false;
                 }
                 }
@@ -391,8 +392,8 @@
 
 
                         maskPos = isRTL ? seekPrevious(buffer, pos) : seekNext(buffer, pos);
                         maskPos = isRTL ? seekPrevious(buffer, pos) : seekNext(buffer, pos);
                     }
                     }
-                    if (isRTL ? activeMaskset['lastValidPosition'] <= opts.numericInput ? getMaskLength() : seekNext(buffer, maskPos) : activeMaskset['lastValidPosition'] >= seekPrevious(buffer, maskPos)) {
-                        if (maskPos >= 0 && maskPos < getMaskLength()) {
+                    if ((isRTL || opts.numericInput) ? activeMaskset['lastValidPosition'] <= opts.numericInput ? getMaskLength(buffer) : seekNext(buffer, maskPos) : activeMaskset['lastValidPosition'] >= seekPrevious(buffer, maskPos)) {
+                        if (maskPos >= 0 && maskPos < getMaskLength(buffer)) {
                             results[index] = _isValid(maskPos, activeMaskset);
                             results[index] = _isValid(maskPos, activeMaskset);
                             if (results[index] !== false) {
                             if (results[index] !== false) {
                                 if (results[index] === true) {
                                 if (results[index] === true) {
@@ -413,12 +414,12 @@
             function determineActiveMasksetIndex(buffer, pos, currentActiveMasksetIndex, isRTL) {
             function determineActiveMasksetIndex(buffer, pos, currentActiveMasksetIndex, isRTL) {
                 $.each(masksets, function (index, value) {
                 $.each(masksets, function (index, value) {
                     var activeMaskset = this;
                     var activeMaskset = this;
-                    if (isRTL ? activeMaskset['lastValidPosition'] <= pos : activeMaskset['lastValidPosition'] >= pos) {
+                    if ((isRTL || opts.numericInput) ? activeMaskset['lastValidPosition'] <= pos : activeMaskset['lastValidPosition'] >= pos) {
                         activeMasksetIndex = index;
                         activeMasksetIndex = index;
                         //reset to correct masktemplate
                         //reset to correct masktemplate
                         if (activeMasksetIndex != currentActiveMasksetIndex) {
                         if (activeMasksetIndex != currentActiveMasksetIndex) {
-                            var abl = getMaskLength(), bufTemplate = getActiveBuffer();
-                            if (isRTL) {
+                            var abl = getMaskLength(buffer), bufTemplate = getActiveBuffer();
+                            if (isRTL || opts.numericInput) {
                                 buffer.reverse();
                                 buffer.reverse();
                                 bufTemplate.reverse();
                                 bufTemplate.reverse();
                             }
                             }
@@ -451,13 +452,13 @@
                 return opts.placeholder.charAt(pos % opts.placeholder.length);
                 return opts.placeholder.charAt(pos % opts.placeholder.length);
             }
             }
 
 
-            function getMaskLength() {
-                return $.inputmask.getMaskLength(getActiveBuffer(), getActiveMaskSet()['greedy'], getActiveMaskSet()['repeat']);
+            function getMaskLength(currentBuffer) {
+                return opts.getMaskLength(getActiveBuffer(), getActiveMaskSet()['greedy'], getActiveMaskSet()['repeat'], currentBuffer, opts);
             }
             }
 
 
             //pos: from position
             //pos: from position
             function seekNext(buffer, pos) {
             function seekNext(buffer, pos) {
-                var maskL = getMaskLength();
+                var maskL = getMaskLength(buffer);
                 if (pos >= maskL) return maskL;
                 if (pos >= maskL) return maskL;
                 var position = pos;
                 var position = pos;
                 while (++position < maskL && !isMask(position)) { };
                 while (++position < maskL && !isMask(position)) { };
@@ -499,7 +500,7 @@
             function prepareBuffer(buffer, position, isRTL) {
             function prepareBuffer(buffer, position, isRTL) {
                 var j;
                 var j;
                 if (isRTL) {
                 if (isRTL) {
-                    while (position < 0 && buffer.length < getMaskLength()) {
+                    while (position < 0 && buffer.length < getMaskLength(buffer)) {
                         j = getActiveBuffer().length - 1;
                         j = getActiveBuffer().length - 1;
                         position = getActiveBuffer().length;
                         position = getActiveBuffer().length;
                         while (getActiveBuffer()[j] !== undefined) {
                         while (getActiveBuffer()[j] !== undefined) {
@@ -507,7 +508,7 @@
                         }
                         }
                     }
                     }
                 } else {
                 } else {
-                    while (buffer[position] == undefined && buffer.length < getMaskLength()) {
+                    while (buffer[position] == undefined && buffer.length < getMaskLength(buffer)) {
                         j = 0;
                         j = 0;
                         while (getActiveBuffer()[j] !== undefined) { //add a new buffer
                         while (getActiveBuffer()[j] !== undefined) { //add a new buffer
                             buffer.push(getActiveBuffer()[j++]);
                             buffer.push(getActiveBuffer()[j++]);
@@ -530,7 +531,7 @@
                 }
                 }
             };
             };
             function clearBuffer(buffer, start, end) {
             function clearBuffer(buffer, start, end) {
-                for (var i = start, maskL = getMaskLength() ; i < end && i < maskL; i++) {
+                for (var i = start, maskL = getMaskLength(buffer) ; i < end && i < maskL; i++) {
                     setBufferElement(buffer, i, getBufferElement(getActiveBuffer().slice(), i));
                     setBufferElement(buffer, i, getBufferElement(getActiveBuffer().slice(), i));
                 }
                 }
             };
             };
@@ -544,8 +545,8 @@
                 var isRTL = $(input).data('inputmask')['isRTL'],
                 var isRTL = $(input).data('inputmask')['isRTL'],
                     inputValue = truncateInput(input._valueGet(), isRTL).split('');
                     inputValue = truncateInput(input._valueGet(), isRTL).split('');
 
 
+                var maskL = getMaskLength(buffer);
                 if (isRTL) { //align inputValue for RTL/numeric input
                 if (isRTL) { //align inputValue for RTL/numeric input
-                    var maskL = getMaskLength();
                     var inputValueRev = inputValue.reverse(); inputValueRev.length = maskL;
                     var inputValueRev = inputValue.reverse(); inputValueRev.length = maskL;
 
 
                     for (var i = 0; i < maskL; i++) {
                     for (var i = 0; i < maskL; i++) {
@@ -561,7 +562,7 @@
                 }
                 }
                 clearBuffer(buffer, 0, buffer.length);
                 clearBuffer(buffer, 0, buffer.length);
                 buffer.length = getActiveBuffer().length;
                 buffer.length = getActiveBuffer().length;
-                var lastMatch = -1, checkPosition = -1, np, maskL = getMaskLength(), ivl = inputValue.length, rtlMatch = ivl == 0 ? maskL : -1;
+                var lastMatch = -1, checkPosition = -1, np, ivl = inputValue.length, rtlMatch = ivl == 0 ? maskL : -1;
                 for (var i = 0; i < ivl; i++) {
                 for (var i = 0; i < ivl; i++) {
                     for (var pos = checkPosition + 1; pos < maskL; pos++) {
                     for (var pos = checkPosition + 1; pos < maskL; pos++) {
                         if (isMask(pos)) {
                         if (isMask(pos)) {
@@ -689,17 +690,17 @@
                 }
                 }
             };
             };
 
 
-            function isComplete(npt) {
-                var complete = false, nptValue = npt._valueGet(), ml = nptValue.length
+            function isComplete(buffer) {
+                var complete = false;
                 currentActiveMasksetIndex = activeMasksetIndex, highestValidPosition = 0;
                 currentActiveMasksetIndex = activeMasksetIndex, highestValidPosition = 0;
                 $.each(masksets, function (ndx, ms) {
                 $.each(masksets, function (ndx, ms) {
                     activeMasksetIndex = ndx;
                     activeMasksetIndex = ndx;
-                    var aml = getMaskLength();
+                    var aml = getMaskLength(buffer);
                     if (ms["lastValidPosition"] >= highestValidPosition && ms["lastValidPosition"] == (aml - 1)) {
                     if (ms["lastValidPosition"] >= highestValidPosition && ms["lastValidPosition"] == (aml - 1)) {
                         var msComplete = true;
                         var msComplete = true;
                         for (var i = 0; i < aml; i++) {
                         for (var i = 0; i < aml; i++) {
                             var mask = isMask(i);
                             var mask = isMask(i);
-                            if ((mask && nptValue.charAt(i) == getPlaceHolder(i)) || (!mask && nptValue.charAt(i) != getActiveBuffer()[i])) {
+                            if ((mask && buffer[i] == getPlaceHolder(i)) || (!mask && buffer[i] != getActiveBuffer()[i])) {
                                 msComplete = false;
                                 msComplete = false;
                                 break;
                                 break;
                             }
                             }
@@ -718,19 +719,19 @@
                 var $input = $(el);
                 var $input = $(el);
                 if (!$input.is(":input")) return;
                 if (!$input.is(":input")) return;
 
 
+                var buffer = getActiveBuffer().slice();
+
                 //correct greedy setting if needed
                 //correct greedy setting if needed
                 getActiveMaskSet()['greedy'] = getActiveMaskSet()['greedy'] ? getActiveMaskSet()['greedy'] : getActiveMaskSet()['repeat'] == 0;
                 getActiveMaskSet()['greedy'] = getActiveMaskSet()['greedy'] ? getActiveMaskSet()['greedy'] : getActiveMaskSet()['repeat'] == 0;
 
 
-
-
                 //handle maxlength attribute
                 //handle maxlength attribute
                 var maxLength = $input.prop('maxLength');
                 var maxLength = $input.prop('maxLength');
-                if (getMaskLength() > maxLength && maxLength > -1) { //FF sets no defined max length to -1 
+                if (getMaskLength(buffer) > maxLength && maxLength > -1) { //FF sets no defined max length to -1 
                     if (maxLength < getActiveBuffer().length) getActiveBuffer().length = maxLength;
                     if (maxLength < getActiveBuffer().length) getActiveBuffer().length = maxLength;
                     if (getActiveMaskSet()['greedy'] == false) {
                     if (getActiveMaskSet()['greedy'] == false) {
                         getActiveMaskSet()['repeat'] = Math.round(maxLength / getActiveBuffer().length);
                         getActiveMaskSet()['repeat'] = Math.round(maxLength / getActiveBuffer().length);
                     }
                     }
-                    $input.prop('maxLength', getMaskLength() * 2);
+                    $input.prop('maxLength', getMaskLength(buffer) * 2);
                 }
                 }
 
 
                 //store tests & original buffer in the input element - used to get the unmasked value
                 //store tests & original buffer in the input element - used to get the unmasked value
@@ -747,11 +748,12 @@
                 //init vars
                 //init vars
                 var buffer = getActiveBuffer().slice(),
                 var buffer = getActiveBuffer().slice(),
                 undoBuffer = el._valueGet(),
                 undoBuffer = el._valueGet(),
+
                 skipKeyPressEvent = false, //Safari 5.1.x - modal dialog fires keypress twice workaround
                 skipKeyPressEvent = false, //Safari 5.1.x - modal dialog fires keypress twice workaround
                 ignorable = false,
                 ignorable = false,
                 lastPosition = -1,
                 lastPosition = -1,
                 firstMaskPos = seekNext(buffer, -1),
                 firstMaskPos = seekNext(buffer, -1),
-                lastMaskPos = seekPrevious(buffer, getMaskLength()),
+                lastMaskPos = seekPrevious(buffer, getMaskLength(buffer)),
                 isRTL = false;
                 isRTL = false;
                 if (el.dir == "rtl" || opts.numericInput) {
                 if (el.dir == "rtl" || opts.numericInput) {
                     el.dir = "ltr"
                     el.dir = "ltr"
@@ -790,7 +792,7 @@
                             clearOptionalTail(input, buffer);
                             clearOptionalTail(input, buffer);
                         }
                         }
                     }
                     }
-                    if (!isComplete(input)) {
+                    if (!isComplete(buffer)) {
                         $input.trigger("incomplete");
                         $input.trigger("incomplete");
                         if (opts.clearIncomplete) {
                         if (opts.clearIncomplete) {
                             if (opts.clearMaskOnLostFocus)
                             if (opts.clearMaskOnLostFocus)
@@ -831,6 +833,7 @@
                         if (selectedCaret.begin == selectedCaret.end) {
                         if (selectedCaret.begin == selectedCaret.end) {
                             var clickPosition = selectedCaret.begin;
                             var clickPosition = selectedCaret.begin;
                             lastPosition = checkVal(input, buffer, false);
                             lastPosition = checkVal(input, buffer, false);
+                            determineInputDirection(input, selectedCaret);
                             if (isRTL)
                             if (isRTL)
                                 caret(input, clickPosition > lastPosition && (isValid(clickPosition, buffer[clickPosition], buffer, true, isRTL) !== false || !isMask(clickPosition)) ? clickPosition : lastPosition);
                                 caret(input, clickPosition > lastPosition && (isValid(clickPosition, buffer[clickPosition], buffer, true, isRTL) !== false || !isMask(clickPosition)) ? clickPosition : lastPosition);
                             else
                             else
@@ -849,7 +852,7 @@
                     var input = this;
                     var input = this;
                     setTimeout(function () {
                     setTimeout(function () {
                         caret(input, checkVal(input, buffer, true));
                         caret(input, checkVal(input, buffer, true));
-                        if (isComplete(input))
+                        if (isComplete(buffer))
                             $input.trigger("complete");
                             $input.trigger("complete");
                     }, 0);
                     }, 0);
                 }).bind('setvalue.inputmask', function () {
                 }).bind('setvalue.inputmask', function () {
@@ -971,16 +974,26 @@
                         }
                         }
                     }
                     }
                 }
                 }
+
+                function determineInputDirection(input, pos) {
+                    //set input direction according the position to the radixPoint
+                    if (opts.numericInput && opts.radixPoint != "") {
+                        var nptStr = input._valueGet();
+                        var radixPosition = nptStr.indexOf(opts.radixPoint);
+                        isRTL = pos.begin <= radixPosition || pos.end <= radixPosition || radixPosition == -1;
+                    }
+                }
+
                 //shift chars to left from start to end and put c at end position if defined
                 //shift chars to left from start to end and put c at end position if defined
                 function shiftL(start, end, c) {
                 function shiftL(start, end, c) {
                     while (!isMask(start) && start - 1 >= 0) start--;
                     while (!isMask(start) && start - 1 >= 0) start--;
-                    for (var i = start; i < end && i < getMaskLength() ; i++) {
+                    for (var i = start; i < end && i < getMaskLength(buffer) ; i++) {
                         if (isMask(i)) {
                         if (isMask(i)) {
                             setReTargetPlaceHolder(buffer, i);
                             setReTargetPlaceHolder(buffer, i);
                             var j = seekNext(buffer, i);
                             var j = seekNext(buffer, i);
                             var p = getBufferElement(buffer, j);
                             var p = getBufferElement(buffer, j);
                             if (p != getPlaceHolder(j)) {
                             if (p != getPlaceHolder(j)) {
-                                if (j < getMaskLength() && isValid(i, p, buffer, true, isRTL) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def) {
+                                if (j < getMaskLength(buffer) && isValid(i, p, buffer, true, isRTL) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def) {
                                     setBufferElement(buffer, i, getBufferElement(buffer, j));
                                     setBufferElement(buffer, i, getBufferElement(buffer, j));
                                     setReTargetPlaceHolder(buffer, j); //cleanup next position
                                     setReTargetPlaceHolder(buffer, j); //cleanup next position
                                 } else {
                                 } else {
@@ -1001,13 +1014,13 @@
                     return start; //return the used start position
                     return start; //return the used start position
                 }
                 }
                 function shiftR(start, end, c, full) { //full => behave like a push right ~ do not stop on placeholders
                 function shiftR(start, end, c, full) { //full => behave like a push right ~ do not stop on placeholders
-                    for (var i = start; i <= end && i < getMaskLength() ; i++) {
+                    for (var i = start; i <= end && i < getMaskLength(buffer) ; i++) {
                         if (isMask(i)) {
                         if (isMask(i)) {
                             var t = getBufferElement(buffer, i);
                             var t = getBufferElement(buffer, i);
                             setBufferElement(buffer, i, c);
                             setBufferElement(buffer, i, c);
                             if (t != getPlaceHolder(i)) {
                             if (t != getPlaceHolder(i)) {
                                 var j = seekNext(buffer, i);
                                 var j = seekNext(buffer, i);
-                                if (j < getMaskLength()) {
+                                if (j < getMaskLength(buffer)) {
                                     if (isValid(j, t, buffer, true, isRTL) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def)
                                     if (isValid(j, t, buffer, true, isRTL) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def)
                                         c = t;
                                         c = t;
                                     else {
                                     else {
@@ -1033,47 +1046,58 @@
 
 
                     var input = this, k = e.keyCode, pos = caret(input);
                     var input = this, k = e.keyCode, pos = caret(input);
 
 
-                    //set input direction according the position to the radixPoint
-                    if (opts.numericInput && opts.radixPoint != "") {
-                        var nptStr = input._valueGet();
-                        var radixPosition = nptStr.indexOf(opts.radixPoint);
-                        if (radixPosition != -1) {
-                            isRTL = pos.begin <= radixPosition || pos.end <= radixPosition;
-                        }
-                    }
+                    determineInputDirection(input, pos);
 
 
                     //backspace, delete, and escape get special treatment
                     //backspace, delete, and escape get special treatment
                     if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iphone && k == 127)) {//backspace/delete
                     if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iphone && k == 127)) {//backspace/delete
-                        var maskL = getMaskLength();
-                        if (pos.begin == 0 && pos.end == maskL) {
+                        var maskL = getMaskLength(buffer);
+                        if (pos.begin == 0 && pos.end == maskL) { //remove full selection
                             activeMasksetIndex = 0; //reset activemask
                             activeMasksetIndex = 0; //reset activemask
                             buffer = getActiveBuffer().slice();
                             buffer = getActiveBuffer().slice();
                             writeBuffer(input, buffer);
                             writeBuffer(input, buffer);
                             caret(input, checkVal(input, buffer, false));
                             caret(input, checkVal(input, buffer, false));
-                        } else if ((pos.end - pos.begin) > 1 || ((pos.end - pos.begin) == 1 && opts.insertMode)) {
+                        } else if ((pos.end - pos.begin) > 1 || ((pos.end - pos.begin) == 1 && opts.insertMode)) { //partial selection
                             clearBuffer(buffer, pos.begin, pos.end);
                             clearBuffer(buffer, pos.begin, pos.end);
                             determineActiveMasksetIndex(buffer, pos.begin, activeMasksetIndex);
                             determineActiveMasksetIndex(buffer, pos.begin, activeMasksetIndex);
                             writeBuffer(input, buffer);
                             writeBuffer(input, buffer);
                             caret(isRTL ? checkVal(input, buffer, false) : pos.begin);
                             caret(isRTL ? checkVal(input, buffer, false) : pos.begin);
-                        } else {
-                            var beginPos = pos.begin - (k == opts.keyCode.DELETE ? 0 : 1);
-                            if (beginPos < firstMaskPos && k == opts.keyCode.DELETE) {
-                                beginPos = firstMaskPos;
-                            }
-                            if (beginPos >= firstMaskPos) {
-                                if (opts.numericInput && getActiveMaskSet()['greedy'] && k == opts.keyCode.DELETE && buffer[beginPos] == opts.radixPoint) {
-                                    beginPos = seekNext(buffer, beginPos);
-                                    isRTL = false;
-                                } else if (opts.numericInput && getActiveMaskSet()['greedy'] && k == opts.keyCode.BACKSPACE && buffer[beginPos] == opts.radixPoint) {
-                                    beginPos--;
-                                    isRTL = true;
+                        } else { //handle delete
+                            var beginPos = pos.begin;
+                            if (k == opts.keyCode.DELETE) {
+                                if (beginPos < firstMaskPos)
+                                    beginPos = firstMaskPos;
+                                if (beginPos < maskL) {
+                                    if (opts.numericInput && opts.radixPoint != "" && buffer[beginPos] == opts.radixPoint) {
+                                        beginPos = (buffer.length - 1 == beginPos) /* radixPoint is latest? delete it */ ? beginPos : seekNext(buffer, beginPos);
+                                        beginPos = shiftL(beginPos, maskL);
+                                    } else {
+                                        if (isRTL) {
+                                            beginPos = shiftR(firstMaskPos, beginPos, getPlaceHolder(beginPos), true);
+                                            beginPos = seekNext(buffer, beginPos);
+                                        } else {
+                                            beginPos = shiftL(beginPos, maskL);
+                                        }
+                                    }
+                                    determineActiveMasksetIndex(buffer, beginPos, activeMasksetIndex);
+                                    writeBuffer(input, buffer, beginPos);
+                                }
+                            } else if (k == opts.keyCode.BACKSPACE) { //handle backspace
+                                if (beginPos > firstMaskPos) {
+                                    beginPos -= 1;
+                                    if (opts.numericInput && opts.radixPoint != "" && buffer[beginPos] == opts.radixPoint) {
+                                        beginPos = shiftR(firstMaskPos, (buffer.length - 1 == beginPos) /* radixPoint is latest? delete it */ ? beginPos : beginPos - 1, getPlaceHolder(beginPos), true);
+                                        beginPos++;
+                                    } else {
+                                        if (isRTL) {
+                                            beginPos = shiftR(firstMaskPos, beginPos, getPlaceHolder(beginPos), true);
+                                            beginPos = buffer[beginPos + 1] == opts.radixPoint ? beginPos + 1 : seekNext(buffer, beginPos);
+                                        } else {
+                                            beginPos = shiftL(beginPos, maskL);
+                                        }
+                                    }
+                                    determineActiveMasksetIndex(buffer, beginPos, activeMasksetIndex);
+                                    writeBuffer(input, buffer, beginPos);
                                 }
                                 }
-                                if (isRTL) {
-                                    beginPos = shiftR(firstMaskPos, beginPos, getPlaceHolder(beginPos), true);
-                                    beginPos = (opts.numericInput && getActiveMaskSet()['greedy'] && k == opts.keyCode.BACKSPACE && buffer[beginPos + 1] == opts.radixPoint) ? beginPos + 1 : seekNext(buffer, beginPos);
-                                } else beginPos = shiftL(beginPos, maskL);
-                                determineActiveMasksetIndex(buffer, beginPos, activeMasksetIndex);
-                                writeBuffer(input, buffer, beginPos);
                             }
                             }
                         }
                         }
                         if (input._valueGet() == getActiveBuffer().join(''))
                         if (input._valueGet() == getActiveBuffer().join(''))
@@ -1083,7 +1107,7 @@
                     } else if (k == opts.keyCode.END || k == opts.keyCode.PAGE_DOWN) { //when END or PAGE_DOWN pressed set position at lastmatch
                     } else if (k == opts.keyCode.END || k == opts.keyCode.PAGE_DOWN) { //when END or PAGE_DOWN pressed set position at lastmatch
                         setTimeout(function () {
                         setTimeout(function () {
                             var caretPos = checkVal(input, buffer, false, true);
                             var caretPos = checkVal(input, buffer, false, true);
-                            if (!opts.insertMode && caretPos == getMaskLength() && !e.shiftKey) caretPos--;
+                            if (!opts.insertMode && caretPos == getMaskLength(buffer) && !e.shiftKey) caretPos--;
                             caret(input, e.shiftKey ? pos.begin : caretPos, caretPos);
                             caret(input, e.shiftKey ? pos.begin : caretPos, caretPos);
                         }, 0);
                         }, 0);
                     } else if (k == opts.keyCode.HOME || k == opts.keyCode.PAGE_UP) {//Home or page_up
                     } else if (k == opts.keyCode.HOME || k == opts.keyCode.PAGE_UP) {//Home or page_up
@@ -1094,7 +1118,7 @@
                         caret(input, 0, checkVal(input, buffer));
                         caret(input, 0, checkVal(input, buffer));
                     } else if (k == opts.keyCode.INSERT) {//insert
                     } else if (k == opts.keyCode.INSERT) {//insert
                         opts.insertMode = !opts.insertMode;
                         opts.insertMode = !opts.insertMode;
-                        caret(input, !opts.insertMode && pos.begin == getMaskLength() ? pos.begin - 1 : pos.begin);
+                        caret(input, !opts.insertMode && pos.begin == getMaskLength(buffer) ? pos.begin - 1 : pos.begin);
                     } else if (e.ctrlKey && k == 88) {
                     } else if (e.ctrlKey && k == 88) {
                         setTimeout(function () {
                         setTimeout(function () {
                             caret(input, checkVal(input, buffer, true));
                             caret(input, checkVal(input, buffer, true));
@@ -1102,7 +1126,7 @@
                     } else if (!opts.insertMode) { //overwritemode
                     } else if (!opts.insertMode) { //overwritemode
                         if (k == opts.keyCode.RIGHT) {//right
                         if (k == opts.keyCode.RIGHT) {//right
                             var caretPos = pos.begin == pos.end ? pos.end + 1 : pos.end;
                             var caretPos = pos.begin == pos.end ? pos.end + 1 : pos.end;
-                            caretPos = caretPos < getMaskLength() ? caretPos : pos.end;
+                            caretPos = caretPos < getMaskLength(buffer) ? caretPos : pos.end;
                             caret(input, e.shiftKey ? pos.begin : caretPos, e.shiftKey ? caretPos + 1 : caretPos);
                             caret(input, e.shiftKey ? pos.begin : caretPos, e.shiftKey ? caretPos + 1 : caretPos);
                         } else if (k == opts.keyCode.LEFT) {//left
                         } else if (k == opts.keyCode.LEFT) {//left
                             var caretPos = pos.begin - 1;
                             var caretPos = pos.begin - 1;
@@ -1129,7 +1153,7 @@
                     if (opts.numericInput && c == opts.radixPoint) {
                     if (opts.numericInput && c == opts.radixPoint) {
                         var nptStr = input._valueGet();
                         var nptStr = input._valueGet();
                         var radixPosition = nptStr.indexOf(opts.radixPoint);
                         var radixPosition = nptStr.indexOf(opts.radixPoint);
-                        caret(input, seekNext(buffer, radixPosition != -1 ? radixPosition : getMaskLength()));
+                        caret(input, seekNext(buffer, radixPosition != -1 ? radixPosition : getMaskLength(buffer)));
                     }
                     }
 
 
                     if (e.ctrlKey || e.altKey || e.metaKey || ignorable) {
                     if (e.ctrlKey || e.altKey || e.metaKey || ignorable) {
@@ -1138,7 +1162,7 @@
                         if (k) {
                         if (k) {
                             $input.trigger('input');
                             $input.trigger('input');
 
 
-                            var pos = caret(input), maskL = getMaskLength(), writeOutBuffer = true;
+                            var pos = caret(input), maskL = getMaskLength(buffer), writeOutBuffer = true;
                             clearBuffer(buffer, pos.begin, pos.end);
                             clearBuffer(buffer, pos.begin, pos.end);
 
 
                             if (isRTL) {
                             if (isRTL) {
@@ -1151,6 +1175,7 @@
                                         c = np.c != undefined ? np.c : c; //set new char from isValid
                                         c = np.c != undefined ? np.c : c; //set new char from isValid
                                     }
                                     }
                                     if (refresh !== true) {
                                     if (refresh !== true) {
+                                        maskL = getMaskLength(buffer); //update masklength to include possible groupSeparator offset
                                         var firstUnmaskedPosition = firstMaskPos;
                                         var firstUnmaskedPosition = firstMaskPos;
                                         if (opts.insertMode == true) {
                                         if (opts.insertMode == true) {
                                             if (getActiveMaskSet()['greedy'] == true) {
                                             if (getActiveMaskSet()['greedy'] == true) {
@@ -1173,7 +1198,7 @@
                                     if (writeOutBuffer) {
                                     if (writeOutBuffer) {
                                         writeBuffer(input, buffer, opts.numericInput ? p + 1 : p);
                                         writeBuffer(input, buffer, opts.numericInput ? p + 1 : p);
                                         setTimeout(function () { //timeout needed for IE
                                         setTimeout(function () { //timeout needed for IE
-                                            if (isComplete(input))
+                                            if (isComplete(buffer))
                                                 $input.trigger("complete");
                                                 $input.trigger("complete");
                                         }, 0);
                                         }, 0);
                                     }
                                     }
@@ -1191,7 +1216,7 @@
                                     }
                                     }
                                     if (refresh !== true) {
                                     if (refresh !== true) {
                                         if (opts.insertMode == true) {
                                         if (opts.insertMode == true) {
-                                            var lastUnmaskedPosition = getMaskLength();
+                                            var lastUnmaskedPosition = getMaskLength(buffer);
                                             var bfrClone = buffer.slice();
                                             var bfrClone = buffer.slice();
                                             while (getBufferElement(bfrClone, lastUnmaskedPosition, true) != getPlaceHolder(lastUnmaskedPosition) && lastUnmaskedPosition >= p) {
                                             while (getBufferElement(bfrClone, lastUnmaskedPosition, true) != getPlaceHolder(lastUnmaskedPosition) && lastUnmaskedPosition >= p) {
                                                 lastUnmaskedPosition = lastUnmaskedPosition == 0 ? -1 : seekPrevious(buffer, lastUnmaskedPosition);
                                                 lastUnmaskedPosition = lastUnmaskedPosition == 0 ? -1 : seekPrevious(buffer, lastUnmaskedPosition);
@@ -1206,7 +1231,7 @@
                                         writeBuffer(input, buffer, next);
                                         writeBuffer(input, buffer, next);
 
 
                                         setTimeout(function () { //timeout needed for IE
                                         setTimeout(function () { //timeout needed for IE
-                                            if (isComplete(input))
+                                            if (isComplete(buffer))
                                                 $input.trigger("complete");
                                                 $input.trigger("complete");
                                         }, 0);
                                         }, 0);
                                     }
                                     }

+ 20 - 3
js/jquery.inputmask.numeric.extensions.js

@@ -21,17 +21,34 @@ Optional extensions on the jquery.inputmask base
             radixPoint: ".",
             radixPoint: ".",
             groupSize: 3,
             groupSize: 3,
             autoGroup: false,
             autoGroup: false,
+            getMaskLength: function (buffer, greedy, repeat, currentBuffer, opts) { //custom getMaskLength to take the groupSeparator into account
+                var calculatedLength = buffer.length;
+
+                if (!greedy && repeat > 1) {
+                    calculatedLength += (buffer.length * (repeat - 1));
+                }
+
+                var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);
+                var escapedRadixPoint = $.inputmask.escapeRegex.call(this, opts.radixPoint);
+                var currentBufferStr = currentBuffer.join(''), strippedBufferStr = currentBufferStr.replace(new RegExp(escapedGroupSeparator, "g"), "").replace(new RegExp(escapedRadixPoint), ""),
+                groupOffset = currentBufferStr.length - strippedBufferStr.length;
+                return calculatedLength + groupOffset;
+            },
             postFormat: function (buffer, pos, reformatOnly, opts) {
             postFormat: function (buffer, pos, reformatOnly, opts) {
                 var cbuf = buffer.slice();
                 var cbuf = buffer.slice();
                 if (!reformatOnly) cbuf.splice(pos, 0, "?"); //set position indicator
                 if (!reformatOnly) cbuf.splice(pos, 0, "?"); //set position indicator
                 var bufVal = cbuf.join('');
                 var bufVal = cbuf.join('');
                 if (opts.autoGroup || (reformatOnly && bufVal.indexOf(opts.groupSeparator) != -1)) {
                 if (opts.autoGroup || (reformatOnly && bufVal.indexOf(opts.groupSeparator) != -1)) {
                     bufVal = bufVal.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                     bufVal = bufVal.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
+                    var radixSplit = bufVal.split(opts.radixPoint);
+                    bufVal = radixSplit[0];
                     var reg = new RegExp('([-\+]?[\\d\?]+)([\\d\?]{' + opts.groupSize + '})');
                     var reg = new RegExp('([-\+]?[\\d\?]+)([\\d\?]{' + opts.groupSize + '})');
                     while (reg.test(bufVal)) {
                     while (reg.test(bufVal)) {
                         bufVal = bufVal.replace(reg, '$1' + opts.groupSeparator + '$2');
                         bufVal = bufVal.replace(reg, '$1' + opts.groupSeparator + '$2');
                         bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator);
                         bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator);
                     }
                     }
+                    if (radixSplit.length > 1)
+                        bufVal += opts.radixPoint + radixSplit[1];
                 }
                 }
                 buffer.length = bufVal.length; //align the length
                 buffer.length = bufVal.length; //align the length
                 for (var i = 0, l = bufVal.length; i < l; i++) {
                 for (var i = 0, l = bufVal.length; i < l; i++) {
@@ -81,7 +98,7 @@ Optional extensions on the jquery.inputmask base
 
 
                         cbuf.splice(pos + 1, 0, chrs);
                         cbuf.splice(pos + 1, 0, chrs);
                         var bufferStr = cbuf.join('');
                         var bufferStr = cbuf.join('');
-                        if (opts.autoGroup) //strip groupseparator
+                        if (opts.autoGroup && !strict) //strip groupseparator
                             bufferStr = bufferStr.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                             bufferStr = bufferStr.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                         var isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                         var isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                         if (!isValid) {
                         if (!isValid) {
@@ -109,7 +126,7 @@ Optional extensions on the jquery.inputmask base
                             }
                             }
                         }
                         }
 
 
-                        if (isValid != false && !strict) {
+                        if (isValid != false && !strict && chrs != opts.radixPoint) {
                             var newPos = opts.postFormat(buffer, pos + 1, false, opts);
                             var newPos = opts.postFormat(buffer, pos + 1, false, opts);
                             return { "pos": newPos };
                             return { "pos": newPos };
                         }
                         }
@@ -140,4 +157,4 @@ Optional extensions on the jquery.inputmask base
             alias: "decimal"
             alias: "decimal"
         }
         }
     });
     });
-})(jQuery);
+})(jQuery);

+ 1 - 1
nuget/jquery.inputmask.nuspec

@@ -25,7 +25,7 @@ Highlights:
 - many features can be enabled/disabled/configured by options
 - many features can be enabled/disabled/configured by options
 - supports readonly/disabled/dir="rtl" attributes
 - supports readonly/disabled/dir="rtl" attributes
 </description>
 </description>
-        <tags>jQuery, plugins</tags>
+        <tags>jQuery, plugins, input, form, inputmask, mask</tags>
     </metadata>
     </metadata>
     <files>
     <files>
         <file src="..\js\jquery.inputmask.date.extensions.js" target="content\Scripts\jquery.inputmask\jquery.inputmask.date.extensions.js" />
         <file src="..\js\jquery.inputmask.date.extensions.js" target="content\Scripts\jquery.inputmask\jquery.inputmask.date.extensions.js" />