Browse Source

update changelog

Robin Herbots 7 years ago
parent
commit
1f6e7b7492
52 changed files with 185 additions and 117 deletions
  1. 3 0
      CHANGELOG.md
  2. 1 0
      README.md
  3. 7 0
      README_date.md
  4. 1 1
      bower.json
  5. 1 1
      component.json
  6. 1 1
      composer.json
  7. 1 1
      dist/inputmask/bindings/inputmask.binding.js
  8. 1 1
      dist/inputmask/dependencyLibs/inputmask.dependencyLib.jqlite.js
  9. 1 1
      dist/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.js
  10. 1 1
      dist/inputmask/dependencyLibs/inputmask.dependencyLib.js
  11. 1 1
      dist/inputmask/global/document.js
  12. 1 1
      dist/inputmask/global/window.js
  13. 14 3
      dist/inputmask/inputmask.date.extensions.js
  14. 1 1
      dist/inputmask/inputmask.extensions.js
  15. 18 11
      dist/inputmask/inputmask.js
  16. 1 1
      dist/inputmask/inputmask.numeric.extensions.js
  17. 1 1
      dist/inputmask/inputmask.phone.extensions.js
  18. 1 1
      dist/inputmask/jquery.inputmask.js
  19. 1 1
      dist/inputmask/phone-codes/phone-be.js
  20. 1 1
      dist/inputmask/phone-codes/phone-ca.js
  21. 1 1
      dist/inputmask/phone-codes/phone-hu.js
  22. 1 1
      dist/inputmask/phone-codes/phone-it.js
  23. 1 1
      dist/inputmask/phone-codes/phone-mx.js
  24. 1 1
      dist/inputmask/phone-codes/phone-nl.js
  25. 1 1
      dist/inputmask/phone-codes/phone-ru.js
  26. 1 1
      dist/inputmask/phone-codes/phone.js
  27. 31 13
      dist/jquery.inputmask.bundle.js
  28. 1 1
      dist/min/inputmask/bindings/inputmask.binding.min.js
  29. 1 1
      dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.jqlite.min.js
  30. 1 1
      dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.min.js
  31. 1 1
      dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.min.js
  32. 1 1
      dist/min/inputmask/global/document.min.js
  33. 1 1
      dist/min/inputmask/global/window.min.js
  34. 2 2
      dist/min/inputmask/inputmask.date.extensions.min.js
  35. 1 1
      dist/min/inputmask/inputmask.extensions.min.js
  36. 2 2
      dist/min/inputmask/inputmask.min.js
  37. 1 1
      dist/min/inputmask/inputmask.numeric.extensions.min.js
  38. 1 1
      dist/min/inputmask/inputmask.phone.extensions.min.js
  39. 1 1
      dist/min/inputmask/jquery.inputmask.min.js
  40. 1 1
      dist/min/inputmask/phone-codes/phone-be.min.js
  41. 1 1
      dist/min/inputmask/phone-codes/phone-ca.min.js
  42. 1 1
      dist/min/inputmask/phone-codes/phone-hu.min.js
  43. 1 1
      dist/min/inputmask/phone-codes/phone-it.min.js
  44. 1 1
      dist/min/inputmask/phone-codes/phone-mx.min.js
  45. 1 1
      dist/min/inputmask/phone-codes/phone-nl.min.js
  46. 1 1
      dist/min/inputmask/phone-codes/phone-ru.min.js
  47. 1 1
      dist/min/inputmask/phone-codes/phone.min.js
  48. 2 2
      dist/min/jquery.inputmask.bundle.min.js
  49. 18 4
      js/inputmask.date.extensions.js
  50. 46 39
      js/inputmask.js
  51. 1 1
      package.json
  52. 1 1
      qunit/tests_optional.js

+ 3 - 0
CHANGELOG.md

@@ -11,6 +11,8 @@
 - CSS Unit Mask #1843
 
 ### Updates
+- make behavior of [] an {0,1} consistent
+- change default value from greedy option to false
 - fix unmatched alternations in gettests. ("[0-9]{2}|[0-9]{3}" like masks)
 - code cleanup and refactoring
     - oncomplete calls
@@ -28,6 +30,7 @@
 
 ### Fixed
 - jitMasking + disablePredictiveText causes android browser tab to stuck when clicked on "backspase" #1862
+- Android 6 issue - Samsung device keyboard #1818
 - Method oncomplete doesn't work correctly with jitMasking #1845
 - isComplete in numeric extensions doesn't take into account negationSymbol #1844
 - Email alias - retype @ removes last . #1324

+ 1 - 0
README.md

@@ -786,6 +786,7 @@ $(document).ready(function(){
 ```
 
 ### greedy
+Default: false
 Toggle to allocate as much possible or the opposite. Non-greedy repeat function.
 
 ```javascript

+ 7 - 0
README_date.md

@@ -76,6 +76,13 @@ GMT/UTC timezone offset, e.g. -0500 or +0230.
 - S  
 The date's ordinal suffix (st, nd, rd, or th). Works well with d.
 
+### Optional parts
+To mark a part of the inputFormat as optional, use the [] as you would for other masks.
+
+Ex.
+inputFormat: "dd/mm/yyyy [HH]"
+
+
 ## displayFormat
 Visual format when the input looses focus
 ## outputFormat

+ 1 - 1
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "inputmask",
-  "version": "4.0.0-beta.48",
+  "version": "4.0.0-beta.51",
   "main": [
 	  "./dist/inputmask/inputmask.js",
 	  "./dist/inputmask/inputmask.extensions.js",

+ 1 - 1
component.json

@@ -2,7 +2,7 @@
 	"name": "inputmask",
 	"repository": "robinherbots/Inputmask",
 	"description": "Inputmask is a javascript library which creates an input mask.  Inputmask can run against vanilla javascript, jQuery and jqlite.",
-	"version": "4.0.0-beta.48",
+	"version": "4.0.0-beta.51",
 	"keywords": [
 		"jquery",
 		"plugins",

+ 1 - 1
composer.json

@@ -1,7 +1,7 @@
 {
   "name": "robinherbots/inputmask",
   "description": "Inputmask is a javascript library which creates an input mask.  Inputmask can run against vanilla javascript, jQuery and jqlite.",
-  "version": "4.0.0-beta.48",
+  "version": "4.0.0-beta.51",
   "type": "library",
   "keywords": ["jquery", "plugins", "input", "form", "inputmask", "mask"],
   "homepage": "http://robinherbots.github.io/Inputmask",

+ 1 - 1
dist/inputmask/bindings/inputmask.binding.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/dependencyLibs/inputmask.dependencyLib.jqlite.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/dependencyLibs/inputmask.dependencyLib.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/global/document.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 "function" == typeof define && define.amd ? define(function() {

+ 1 - 1
dist/inputmask/global/window.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 "function" == typeof define && define.amd ? define(function() {

+ 14 - 3
dist/inputmask/inputmask.date.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {
@@ -77,7 +77,18 @@
     }
     function parse(format, dateObjValue, opts) {
         for (var match, mask = ""; match = getTokenizer(opts).exec(format); ) {
-            if (void 0 === dateObjValue) mask += formatCode[match[0]] ? "(" + formatCode[match[0]][0] + ")" : Inputmask.escapeRegex(match[0]); else if (formatCode[match[0]]) mask += formatCode[match[0]][3].call(dateObjValue.date); else mask += match[0];
+            if (void 0 === dateObjValue) if (formatCode[match[0]]) mask += "(" + formatCode[match[0]][0] + ")"; else switch (match[0]) {
+              case "[":
+                mask += "(";
+                break;
+
+              case "]":
+                mask += ")?";
+                break;
+
+              default:
+                mask += Inputmask.escapeRegex(match[0]);
+            } else if (formatCode[match[0]]) mask += formatCode[match[0]][3].call(dateObjValue.date); else mask += match[0];
         }
         return mask;
     }
@@ -114,7 +125,7 @@
                 return formatCode.S = opts.i18n.ordinalSuffix.join("|"), opts.inputFormat = formatAlias[opts.inputFormat] || opts.inputFormat, 
                 opts.displayFormat = formatAlias[opts.displayFormat] || opts.displayFormat || opts.inputFormat, 
                 opts.outputFormat = formatAlias[opts.outputFormat] || opts.outputFormat || opts.inputFormat, 
-                opts.placeholder = "" !== opts.placeholder ? opts.placeholder : opts.inputFormat, 
+                opts.placeholder = "" !== opts.placeholder ? opts.placeholder : opts.inputFormat.replace(/[\[\]]/, ""), 
                 opts.min = analyseMask(opts.min, opts.inputFormat, opts), opts.max = analyseMask(opts.max, opts.inputFormat, opts), 
                 opts.regex = parse(opts.inputFormat, void 0, opts), null;
             },

+ 1 - 1
dist/inputmask/inputmask.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

File diff suppressed because it is too large
+ 18 - 11
dist/inputmask/inputmask.js


+ 1 - 1
dist/inputmask/inputmask.numeric.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/inputmask.phone.extensions.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/jquery.inputmask.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-be.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-ca.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-hu.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-it.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-mx.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-nl.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone-ru.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

+ 1 - 1
dist/inputmask/phone-codes/phone.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(factory) {

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


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


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


+ 1 - 1
dist/min/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.min.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 !function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e(require("jquery")):window.dependencyLib=e(jQuery)}(function(e){return e});

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


+ 1 - 1
dist/min/inputmask/global/document.min.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 "function"==typeof define&&define.amd?define(function(){return document}):"object"==typeof exports&&(module.exports=document);

+ 1 - 1
dist/min/inputmask/global/window.min.js

@@ -3,7 +3,7 @@
 * https://github.com/RobinHerbots/Inputmask
 * Copyright (c) 2010 - 2018 Robin Herbots
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
-* Version: 4.0.0-beta.48
+* Version: 4.0.0-beta.51
 */
 
 "function"==typeof define&&define.amd?define(function(){return window}):"object"==typeof exports&&(module.exports=window);

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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


+ 18 - 4
js/inputmask.date.extensions.js

@@ -118,8 +118,22 @@
         //parse format to regex string
         var mask = "", match;
         while (match = getTokenizer(opts).exec(format)) {
-            if (dateObjValue === undefined)
-                mask += formatCode[match[0]] ? "(" + formatCode[match[0]][0] + ")" : Inputmask.escapeRegex(match[0]);
+            if (dateObjValue === undefined) {
+                if (formatCode[match[0]]) {
+                    mask += "(" + formatCode[match[0]][0] + ")";
+                } else {
+                    switch (match[0]) {
+                        case "[":
+                            mask += "(";
+                            break;
+                        case "]":
+                            mask += ")?";
+                            break;
+                        default:
+                            mask += Inputmask.escapeRegex(match[0]);
+                    }
+                }
+            }
             else {
                 if (formatCode[match[0]]) {
                     var getFn = formatCode[match[0]][3];
@@ -148,7 +162,7 @@
                 correctedyear = correctedyear.replace(/[^0-9]/g, "");
                 correctedyear += opts.min.year == opts.max.year ?
                     opts.min.year.substr(correctedyear.length) :
-                    (correctedyear !== "" && opts.max.year.indexOf(correctedyear) == 0 ? parseInt(opts.max.year) -1 : parseInt(opts.min.year) + 1).toString().substr(correctedyear.length);
+                    (correctedyear !== "" && opts.max.year.indexOf(correctedyear) == 0 ? parseInt(opts.max.year) - 1 : parseInt(opts.min.year) + 1).toString().substr(correctedyear.length);
             } else correctedyear = correctedyear.replace(/[^0-9]/g, "0");
             return correctedyear;
         }
@@ -189,7 +203,7 @@
                 opts.inputFormat = formatAlias[opts.inputFormat] || opts.inputFormat; //resolve possible formatAkias
                 opts.displayFormat = formatAlias[opts.displayFormat] || opts.displayFormat || opts.inputFormat; //resolve possible formatAkias
                 opts.outputFormat = formatAlias[opts.outputFormat] || opts.outputFormat || opts.inputFormat; //resolve possible formatAkias
-                opts.placeholder = opts.placeholder !== "" ? opts.placeholder : opts.inputFormat;
+                opts.placeholder = opts.placeholder !== "" ? opts.placeholder : opts.inputFormat.replace(/[\[\]]/, "");
                 opts.min = analyseMask(opts.min, opts.inputFormat, opts);
                 opts.max = analyseMask(opts.max, opts.inputFormat, opts);
                 opts.regex = parse(opts.inputFormat, undefined, opts);

+ 46 - 39
js/inputmask.js

@@ -63,7 +63,7 @@
                 onincomplete: $.noop, //executes when the mask is incomplete and focus is lost
                 oncleared: $.noop, //executes when the mask is cleared
                 repeat: 0, //repetitions of the mask: * ~ forever, otherwise specify an integer
-                greedy: true, //true: allocated buffer for the mask and repetitions - false: allocate only if needed
+                greedy: false, //true: allocated buffer for the mask and repetitions - false: allocate only if needed
                 autoUnmask: false, //automatically unmask when retrieving the value with $.fn.val or value if the browser supports __lookupGetter__ or getOwnPropertyDescriptor
                 removeMaskOnSubmit: false, //remove the mask before submitting the form.
                 clearMaskOnLostFocus: true,
@@ -328,7 +328,7 @@
                         if (element.indexOf("[") === 0 || (escaped && /\\d|\\s|\\w]/i.test(element)) || element === ".") {
                             mtoken.matches.splice(position++, 0, {
                                 fn: new RegExp(element, opts.casing ? "i" : ""),
-                                optionality: mtoken.isOptional,
+                                optionality: false,
                                 newBlockMarker: prevMatch === undefined || prevMatch.def !== element,
                                 casing: null,
                                 def: element,
@@ -341,7 +341,7 @@
                                 prevMatch = mtoken.matches[position - 1];
                                 mtoken.matches.splice(position++, 0, {
                                     fn: null,
-                                    optionality: mtoken.isOptional,
+                                    optionality: false,
                                     newBlockMarker: prevMatch === undefined || (prevMatch.def !== lmnt && prevMatch.fn !== null),
                                     casing: null,
                                     def: opts.staticDefinitionSymbol || lmnt,
@@ -358,7 +358,7 @@
                                 fn: maskdef.validator ? typeof maskdef.validator == "string" ? new RegExp(maskdef.validator, opts.casing ? "i" : "") : new function () {
                                     this.test = maskdef.validator;
                                 } : new RegExp("."),
-                                optionality: mtoken.isOptional,
+                                optionality: false,
                                 newBlockMarker: prevMatch === undefined || prevMatch.def !== (maskdef.definitionSymbol || element),
                                 casing: maskdef.casing,
                                 def: maskdef.definitionSymbol || element,
@@ -368,7 +368,7 @@
                         } else {
                             mtoken.matches.splice(position++, 0, {
                                 fn: null,
-                                optionality: mtoken.isOptional,
+                                optionality: false,
                                 newBlockMarker: prevMatch === undefined || (prevMatch.def !== element && prevMatch.fn !== null),
                                 casing: null,
                                 def: opts.staticDefinitionSymbol || element,
@@ -821,15 +821,20 @@
                 trackCaret = false;
 
             //maskset helperfunctions
-            function getMaskTemplate(baseOnInput, minimalPos, includeMode, noJit) {
+            function getMaskTemplate(baseOnInput, minimalPos, includeMode, noJit, clearOptionalTail) {
                 //includeMode true => input, undefined => placeholder, false => mask
+
+                var greedy = opts.greedy;
+                if (clearOptionalTail) opts.greedy = false;
                 minimalPos = minimalPos || 0;
                 var maskTemplate = [],
                     ndxIntlzr, pos = 0,
                     test, testPos, lvp = getLastValidPosition();
                 do {
                     if (baseOnInput === true && getMaskSet().validPositions[pos]) {
-                        testPos = getMaskSet().validPositions[pos];
+                        testPos = (clearOptionalTail && getMaskSet().validPositions[pos].match.optionality === true && (getMaskSet().validPositions[pos].generatedInput === true || getMaskSet().validPositions[pos].input == opts.skipOptionalPartCharacter) && getMaskSet().validPositions[pos + 1] === undefined)
+                            ? determineTestTemplate(pos, getTests(pos, ndxIntlzr, pos - 1))
+                            : getMaskSet().validPositions[pos];
                         test = testPos.match;
                         ndxIntlzr = testPos.locator.slice();
                         maskTemplate.push(includeMode === true ? testPos.input : includeMode === false ? test.nativeDef : getPlaceholder(pos, test));
@@ -856,6 +861,8 @@
                 if (includeMode !== false || //do not alter the masklength when just retrieving the maskdefinition
                     getMaskSet().maskLength === undefined) //just make sure the maskLength gets initialized in all cases (needed for isValid)
                     getMaskSet().maskLength = pos - 1;
+
+                opts.greedy = greedy;
                 return maskTemplate;
             }
 
@@ -907,13 +914,14 @@
                     }
                 }
 
-                // var controlPos = determineTestTemplate2(pos, tests, guessNextBest);
-                //
-                // if (controlPos != testPos) {
-                //     debugger;
-                //     console.table(controlPos);
-                //     console.table(testPos);
-                // }
+                var controlPos = determineTestTemplate2(pos, tests, guessNextBest);
+
+                if (controlPos != testPos) {
+                    // debugger;
+                    console.log(pos + " 1) " + JSON.stringify(testPos));
+                    console.log(pos + " 2) " + JSON.stringify(controlPos));
+                    determineTestTemplate2(pos, tests, guessNextBest);
+                }
 
                 return testPos;
             }
@@ -928,21 +936,25 @@
 
             function getLocator(tst, align) { //need to align the locators to be correct
                 var locator = (tst.alternation != undefined ? tst.mloc[getDecisionTaker(tst)] : tst.locator).join("");
-                while (locator.length < align) locator += "0";
+                if (locator !== "") while (locator.length < align) locator += "0";
                 return locator;
             }
 
             function determineTestTemplate2(pos, tests, guessNextBest) {
                 pos = pos > 0 ? pos - 1 : 0;
                 var altTest = getTest(pos), targetLocator = getLocator(altTest), tstLocator, closest, bestMatch;
-                $.each(tests, function (ndx, tst) { //find best matching
+                for (var ndx = 0; ndx < tests.length; ndx++) { //find best matching
+                    var tst = tests[ndx];
                     tstLocator = getLocator(tst, targetLocator.length);
                     var distance = Math.abs(tstLocator - targetLocator);
-                    if (closest === undefined || (tstLocator !== "" && distance < closest)) {
+                    if (closest === undefined
+                        || (tstLocator !== "" && distance < closest)
+                        || (bestMatch && bestMatch.match.optionality && (!tst.match.optionality || !tst.match.newBlockMarker))
+                        || (bestMatch && bestMatch.match.optionalQuantifier && !tst.match.optionalQuantifier)) {
                         closest = distance;
                         bestMatch = tst;
                     }
-                });
+                }
 
                 return bestMatch;
             }
@@ -1089,6 +1101,10 @@
                                 var optionalToken = match;
                                 match = resolveTestFromToken(match, ndxInitializer, loopNdx, quantifierRecurse);
                                 if (match) {
+                                    //mark optionality in matches
+                                    $.each(matches, function (ndx, mtch) {
+                                        mtch.match.optionality = true;
+                                    });
                                     latestMatch = matches[matches.length - 1].match;
                                     if (quantifierRecurse === undefined && isFirstMatch(latestMatch, optionalToken)) { //prevent loop see #698
                                         insertStop = true; //insert a stop
@@ -1290,7 +1306,7 @@
                     matches.push({
                         match: {
                             fn: null,
-                            optionality: true,
+                            optionality: false,
                             casing: null,
                             def: "",
                             placeholder: ""
@@ -1628,7 +1644,7 @@
                 return result;
             }
 
-            //fill in best positions according the current input
+//fill in best positions according the current input
             function trackbackPositions(originalPos, newPos, fillOnly) {
                 var result;
                 if (originalPos === undefined) {
@@ -1887,6 +1903,11 @@
                                     }
                                     if (mobile) {
                                         trackCaret = true;
+                                        var args = arguments;
+                                        setTimeout(function () { //needed for caret selection when entering a char on Android 8 - #1818
+                                            eventHandler.apply(that, args);
+                                        }, 0);
+                                        return false;
                                     }
                                     break;
                                 case "keydown":
@@ -2660,24 +2681,9 @@
             }
 
             function clearOptionalTail(buffer) {
-                var rl = determineLastRequiredPosition(),
-                    validPos, bl = buffer.length;
-
-                var lv = getMaskSet().validPositions[getLastValidPosition()];
-                while (rl < bl &&
-                !isMask(rl, true) &&
-                (validPos = (lv !== undefined ? getTestTemplate(rl, lv.locator.slice(""), lv) : getTest(rl))) &&
-                validPos.match.optionality !== true &&
-                ((validPos.match.optionalQuantifier !== true && validPos.match.newBlockMarker !== true) || (rl + 1 === bl &&
-                    (lv !== undefined ? getTestTemplate(rl + 1, lv.locator.slice(""), lv) : getTest(rl + 1)).match.def === ""))) {
-                    rl++;
-                }
-
-                //exceptionally strip from the validatedPositions
-                while ((validPos = getMaskSet().validPositions[rl - 1]) && validPos && validPos.match.optionality && validPos.input === opts.skipOptionalPartCharacter) {
-                    rl--;
-                }
-                buffer.splice(rl);
+                buffer.length = 0;
+                var template = getMaskTemplate(true, 0, true, undefined, true), lmnt, validPos;
+                while (lmnt = template.shift(), lmnt !== undefined) buffer.push(lmnt);
                 return buffer;
             }
 
@@ -3256,4 +3262,5 @@
 //make inputmask available
         return Inputmask;
     }
-));
+))
+;

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "inputmask",
-  "version": "4.0.0-beta.48",
+  "version": "4.0.0-beta.51",
   "description": "Inputmask is a javascript library which creates an input mask.  Inputmask can run against vanilla javascript, jQuery and jqlite.",
   "main": "index.js",
   "files": [

+ 1 - 1
qunit/tests_optional.js

@@ -77,7 +77,7 @@ export default function (qunit, $, Inputmask) {
 
 		testmask.focus();
 		$("#testmask").Type("123456");
-		assert.equal(testmask.value, "12345-6", "Result " + testmask.value);
+		assert.equal(testmask.value, "12345-6___", "Result " + testmask.value);
 	});
 
 	qunit.test("inputmask({ mask: \"99999[-9999]\", greedy: false }) - input 123456789", function (assert) {