|
|
@@ -33,7 +33,7 @@
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- function generateMaskSet(opts) {
|
|
|
+ function generateMaskSet(opts, multi) {
|
|
|
var ms = [];
|
|
|
|
|
|
function analyseMask(mask) {
|
|
|
@@ -49,7 +49,7 @@
|
|
|
this.quantifier = { min: 1, max: 1 };
|
|
|
};
|
|
|
|
|
|
- //test definition => {fn: RegExp/function, cardinality: int, optionality: bool, newBlockMarker: bool, offset: int, casing: null/upper/lower, def: definitionSymbol, placeholder: placeholder}
|
|
|
+ //test definition => {fn: RegExp/function, cardinality: int, optionality: bool, newBlockMarker: bool, casing: null/upper/lower, def: definitionSymbol, placeholder: placeholder, mask: real maskDefinition}
|
|
|
function insertTestDefinition(mtoken, element, position) {
|
|
|
var maskdef = opts.definitions[element];
|
|
|
var newBlockMarker = mtoken.matches.length == 0;
|
|
|
@@ -58,20 +58,21 @@
|
|
|
var prevalidators = maskdef["prevalidator"], prevalidatorsL = prevalidators ? prevalidators.length : 0;
|
|
|
for (var i = 1; i < maskdef.cardinality; i++) {
|
|
|
var prevalidator = prevalidatorsL >= i ? prevalidators[i - 1] : [], validator = prevalidator["validator"], cardinality = prevalidator["cardinality"];
|
|
|
- mtoken.matches.splice(position++, 0, { fn: validator ? typeof validator == 'string' ? new RegExp(validator) : new function () { this.test = validator; } : new RegExp("."), cardinality: cardinality ? cardinality : 1, optionality: mtoken.isOptional, newBlockMarker: newBlockMarker, casing: maskdef["casing"], def: maskdef["definitionSymbol"] || element, placeholder: maskdef["placeholder"] });
|
|
|
+ mtoken.matches.splice(position++, 0, { fn: validator ? typeof validator == 'string' ? new RegExp(validator) : new function () { this.test = validator; } : new RegExp("."), cardinality: cardinality ? cardinality : 1, optionality: mtoken.isOptional, newBlockMarker: newBlockMarker, casing: maskdef["casing"], def: maskdef["definitionSymbol"] || element, placeholder: maskdef["placeholder"], mask: element });
|
|
|
}
|
|
|
- mtoken.matches.splice(position++, 0, { fn: maskdef.validator ? typeof maskdef.validator == 'string' ? new RegExp(maskdef.validator) : new function () { this.test = maskdef.validator; } : new RegExp("."), cardinality: maskdef.cardinality, optionality: mtoken.isOptional, newBlockMarker: newBlockMarker, casing: maskdef["casing"], def: maskdef["definitionSymbol"] || element, placeholder: maskdef["placeholder"] });
|
|
|
+ mtoken.matches.splice(position++, 0, { fn: maskdef.validator ? typeof maskdef.validator == 'string' ? new RegExp(maskdef.validator) : new function () { this.test = maskdef.validator; } : new RegExp("."), cardinality: maskdef.cardinality, optionality: mtoken.isOptional, newBlockMarker: newBlockMarker, casing: maskdef["casing"], def: maskdef["definitionSymbol"] || element, placeholder: maskdef["placeholder"], mask: element });
|
|
|
} else {
|
|
|
- mtoken.matches.splice(position++, 0, { fn: null, cardinality: 0, optionality: mtoken.isOptional, newBlockMarker: newBlockMarker, casing: null, def: element, placeholder: undefined });
|
|
|
+ mtoken.matches.splice(position++, 0, { fn: null, cardinality: 0, optionality: mtoken.isOptional, newBlockMarker: newBlockMarker, casing: null, def: element, placeholder: undefined, mask: element });
|
|
|
escaped = false;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- var currentToken = new maskToken(),
|
|
|
- match,
|
|
|
- m,
|
|
|
- openenings = [],
|
|
|
- maskTokens = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ var currentToken = new maskToken(),
|
|
|
+ match,
|
|
|
+ m,
|
|
|
+ openenings = [],
|
|
|
+ maskTokens = [],
|
|
|
+ openingToken;
|
|
|
|
|
|
while (match = tokenizer.exec(mask)) {
|
|
|
m = match[0];
|
|
|
@@ -80,7 +81,7 @@
|
|
|
// optional closing
|
|
|
case opts.groupmarker.end:
|
|
|
// Group closing
|
|
|
- var openingToken = openenings.pop();
|
|
|
+ openingToken = openenings.pop();
|
|
|
if (openenings.length > 0) {
|
|
|
openenings[openenings.length - 1]["matches"].push(openingToken);
|
|
|
} else {
|
|
|
@@ -109,7 +110,7 @@
|
|
|
quantifier.quantifier = { min: mq0, max: mq1 };
|
|
|
if (openenings.length > 0) {
|
|
|
var matches = openenings[openenings.length - 1]["matches"];
|
|
|
- var match = matches.pop();
|
|
|
+ match = matches.pop();
|
|
|
if (!match["isGroup"]) {
|
|
|
var groupToken = new maskToken(true);
|
|
|
groupToken.matches.push(match);
|
|
|
@@ -118,7 +119,7 @@
|
|
|
matches.push(match);
|
|
|
matches.push(quantifier);
|
|
|
} else {
|
|
|
- var match = currentToken.matches.pop();
|
|
|
+ match = currentToken.matches.pop();
|
|
|
if (!match["isGroup"]) {
|
|
|
var groupToken = new maskToken(true);
|
|
|
groupToken.matches.push(match);
|
|
|
@@ -132,11 +133,33 @@
|
|
|
escaped = true;
|
|
|
break;
|
|
|
case opts.alternatormarker:
|
|
|
-
|
|
|
+ var alternator = new maskToken(false, false, false, true);
|
|
|
+ if (openenings.length > 0) {
|
|
|
+ var matches = openenings[openenings.length - 1]["matches"];
|
|
|
+ match = matches.pop();
|
|
|
+ alternator.matches.push(match);
|
|
|
+ openenings.push(alternator);
|
|
|
+ } else {
|
|
|
+ match = currentToken.matches.pop();
|
|
|
+ alternator.matches.push(match);
|
|
|
+ openenings.push(alternator);
|
|
|
+ }
|
|
|
break;
|
|
|
default:
|
|
|
if (openenings.length > 0) {
|
|
|
insertTestDefinition(openenings[openenings.length - 1], m);
|
|
|
+ var lastToken = openenings[openenings.length - 1];
|
|
|
+ if (lastToken["isAlternator"]) {
|
|
|
+ openingToken = openenings.pop();
|
|
|
+ for (var mndx = 0; mndx < openingToken.matches.length; mndx++) {
|
|
|
+ openingToken.matches[mndx].isGroup = false; //don't mark alternate groups as group
|
|
|
+ }
|
|
|
+ if (openenings.length > 0) {
|
|
|
+ openenings[openenings.length - 1]["matches"].push(openingToken);
|
|
|
+ } else {
|
|
|
+ currentToken.matches.push(openingToken);
|
|
|
+ }
|
|
|
+ }
|
|
|
} else {
|
|
|
if (currentToken.matches.length > 0) {
|
|
|
var lastMatch = currentToken.matches[currentToken.matches.length - 1];
|
|
|
@@ -149,8 +172,17 @@
|
|
|
insertTestDefinition(currentToken, m);
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
+ }
|
|
|
+
|
|
|
+ if (openenings.length > 0) {
|
|
|
+ var lastToken = openenings[openenings.length - 1];
|
|
|
+ if (lastToken["isAlternator"]) {
|
|
|
+ for (var mndx = 0; mndx < lastToken.matches.length; mndx++) {
|
|
|
+ lastToken.matches[mndx].isGroup = false; //don't mark alternate groups as group
|
|
|
+ }
|
|
|
+ }
|
|
|
+ currentToken.matches = currentToken.matches.concat(openenings);
|
|
|
+ }
|
|
|
if (currentToken.matches.length > 0) {
|
|
|
var lastMatch = currentToken.matches[currentToken.matches.length - 1];
|
|
|
if (lastMatch["isGroup"]) { //this is not a group but a normal mask => convert
|
|
|
@@ -207,13 +239,18 @@
|
|
|
opts.mask = opts.mask.call(this, opts);
|
|
|
}
|
|
|
if ($.isArray(opts.mask)) {
|
|
|
- $.each(opts.mask, function (ndx, msk) {
|
|
|
- if (msk["mask"] != undefined) {
|
|
|
- ms.push(generateMask(msk["mask"].toString(), msk));
|
|
|
- } else {
|
|
|
- ms.push(generateMask(msk.toString()));
|
|
|
- }
|
|
|
- });
|
|
|
+ if (multi) {
|
|
|
+ $.each(opts.mask, function (ndx, msk) {
|
|
|
+ if (msk["mask"] != undefined) {
|
|
|
+ ms.push(generateMask(msk["mask"].toString(), msk));
|
|
|
+ } else {
|
|
|
+ ms.push(generateMask(msk.toString()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ var altMask = "(" + opts.mask.join(")|(") + ")";
|
|
|
+ ms = generateMask(altMask);
|
|
|
+ }
|
|
|
} else {
|
|
|
if (opts.mask.length == 1 && opts.greedy == false && opts.repeat != 0) {
|
|
|
opts.placeholder = "";
|
|
|
@@ -421,8 +458,39 @@
|
|
|
}
|
|
|
testPos = pos; //match the position after the group
|
|
|
}
|
|
|
- } else if (match.isAlternator) {
|
|
|
- //TODO
|
|
|
+ } else if (match.isAlternator) {
|
|
|
+ var alternateToken = match;
|
|
|
+ var currentMatches = matches.slice(), malternate1, malternate2, loopNdxCnt = loopNdx.length;
|
|
|
+ var altIndex = ndxInitializer.length > 0 ? ndxInitializer.shift() : -1;
|
|
|
+ if (altIndex == -1) {
|
|
|
+ var currentPos = testPos;
|
|
|
+ matches = [];
|
|
|
+ match = ResolveTestFromToken(alternateToken.matches[0], ndxInitializer.slice(), [0].concat(loopNdx), quantifierRecurse);
|
|
|
+ malternate1 = matches.slice();
|
|
|
+ testPos = currentPos;
|
|
|
+ matches = [];
|
|
|
+ match = ResolveTestFromToken(alternateToken.matches[1], ndxInitializer, [1].concat(loopNdx), quantifierRecurse);
|
|
|
+ malternate2 = matches.slice();
|
|
|
+ //fuzzy merge matches
|
|
|
+ matches = [];
|
|
|
+ for (var ndx1 = 0; ndx1 < malternate1.length; ndx1++) {
|
|
|
+ var altMatch = malternate1[ndx1]; currentMatches.push(altMatch);
|
|
|
+ for (var ndx2 = 0; ndx2 < malternate2.length; ndx2++) {
|
|
|
+ var altMatch2 = malternate2[ndx2];
|
|
|
+ //verify equality
|
|
|
+ if (altMatch.match.mask == altMatch2.match.mask) {
|
|
|
+ malternate2.splice(ndx2, 1);
|
|
|
+ altMatch.locator[loopNdxCnt] = -1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ matches = currentMatches.concat(malternate2);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ match = handleMatch(alternateToken.matches[altIndex], [altIndex].concat(loopNdx), quantifierRecurse);
|
|
|
+ }
|
|
|
+ if (match) return true;
|
|
|
} else if (match.isQuantifier && quantifierRecurse !== true) {
|
|
|
var qt = match;
|
|
|
opts.greedy = opts.greedy && isFinite(qt.quantifier.max); //greedy must be off when * or + is used (always!!)
|
|
|
@@ -633,7 +701,10 @@
|
|
|
}
|
|
|
|
|
|
var maskPos = pos;
|
|
|
- if (maskPos >= getMaskLength()) return false;
|
|
|
+ if (maskPos >= getMaskLength()) {
|
|
|
+ // console.log("try alternate match");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
var result = _isValid(maskPos, c, strict, fromSetValid);
|
|
|
if (!strict && result === false) {
|
|
|
var currentPosValid = getMaskSet()["validPositions"][maskPos];
|
|
|
@@ -1631,11 +1702,11 @@
|
|
|
case "mask":
|
|
|
//resolve possible aliases given by options
|
|
|
resolveAlias(opts.alias, options, opts);
|
|
|
- maskset = generateMaskSet(opts);
|
|
|
+ maskset = generateMaskSet(opts, targetScope !== maskScope);
|
|
|
if (maskset.length == 0) { return this; }
|
|
|
|
|
|
return this.each(function () {
|
|
|
- targetScope({ "action": "mask", "el": this }, $.extend(true, {}, $.isArray(maskset) && targetScope === maskScope ? maskset[0] : maskset), importAttributeOptions(this, opts));
|
|
|
+ targetScope({ "action": "mask", "el": this }, $.extend(true, {}, maskset), importAttributeOptions(this, opts));
|
|
|
});
|
|
|
case "unmaskedvalue":
|
|
|
var $input = $(this);
|
|
|
@@ -1683,20 +1754,20 @@
|
|
|
//set mask
|
|
|
opts.mask = fn;
|
|
|
}
|
|
|
- maskset = generateMaskSet(opts);
|
|
|
+ maskset = generateMaskSet(opts, targetScope !== maskScope);
|
|
|
if (maskset == undefined) { return this; }
|
|
|
return this.each(function () {
|
|
|
- targetScope({ "action": "mask", "el": this }, $.extend(true, {}, $.isArray(maskset) && targetScope === maskScope ? maskset[0] : maskset), importAttributeOptions(this, opts));
|
|
|
+ targetScope({ "action": "mask", "el": this }, $.extend(true, {}, maskset), importAttributeOptions(this, opts));
|
|
|
});
|
|
|
}
|
|
|
} else if (typeof fn == "object") {
|
|
|
opts = $.extend(true, {}, $.inputmask.defaults, fn);
|
|
|
|
|
|
resolveAlias(opts.alias, fn, opts); //resolve aliases
|
|
|
- maskset = generateMaskSet(opts);
|
|
|
+ maskset = generateMaskSet(opts, targetScope !== maskScope);
|
|
|
if (maskset == undefined) { return this; }
|
|
|
return this.each(function () {
|
|
|
- targetScope({ "action": "mask", "el": this }, $.extend(true, {}, $.isArray(maskset) && targetScope === maskScope ? maskset[0] : maskset), importAttributeOptions(this, opts));
|
|
|
+ targetScope({ "action": "mask", "el": this }, $.extend(true, {}, maskset), importAttributeOptions(this, opts));
|
|
|
});
|
|
|
} else if (fn == undefined) {
|
|
|
//look for data-inputmask atribute - the attribute should only contain optipns
|