1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 09:49:28 +02:00
Oinktube/node_modules/inputmask/lib/validation-tests.js

1021 lines
33 KiB
JavaScript

import Inputmask from "./inputmask";
import { getLastValidPosition, seekNext } from "./positioning";
export {
determineTestTemplate,
getDecisionTaker,
getMaskTemplate,
getPlaceholder,
getTest,
getTests,
getTestTemplate,
isSubsetOf
};
function getLocator(tst, align) {
// need to align the locators to be correct
let locator = (
tst.alternation != undefined ? tst.mloc[getDecisionTaker(tst)] : tst.locator
).join("");
if (locator !== "") {
locator = locator.split(":")[0]; // strip off alternation marker
while (locator.length < align) locator += "0";
}
return locator;
}
function getDecisionTaker(tst) {
let decisionTaker = tst.locator[tst.alternation];
if (typeof decisionTaker === "string" && decisionTaker.length > 0) {
// no decision taken ~ take first one as decider
decisionTaker = decisionTaker.split(",")[0];
}
return decisionTaker !== undefined ? decisionTaker.toString() : "";
}
// tobe put on prototype?
function getPlaceholder(pos, test, returnPL) {
const inputmask = this,
opts = this.opts,
maskset = this.maskset;
test = test || getTest.call(inputmask, pos).match;
if (test.placeholder !== undefined || returnPL === true) {
if (
test.placeholder !== "" &&
test.static === true &&
test.generated !== true
) {
// static and not dynamically generated ~ does not occur in regex mask ~ numeric alias def is not a valid entry
const lvp = getLastValidPosition.call(inputmask, pos),
nextPos = seekNext.call(inputmask, lvp);
return (returnPL ? pos <= nextPos : pos < nextPos)
? opts.staticDefinitionSymbol && test.static
? test.nativeDef
: test.def
: typeof test.placeholder === "function"
? test.placeholder(opts)
: test.placeholder;
} else {
return typeof test.placeholder === "function"
? test.placeholder(opts)
: test.placeholder;
}
} else if (test.static === true) {
if (pos > -1 && maskset.validPositions[pos] === undefined) {
let tests = getTests.call(inputmask, pos),
staticAlternations = [],
prevTest;
if (
typeof opts.placeholder === "string" &&
tests.length > 1 + (tests[tests.length - 1].match.def === "" ? 1 : 0)
) {
for (let i = 0; i < tests.length; i++) {
if (
tests[i].match.def !== "" &&
tests[i].match.optionality !== true &&
tests[i].match.optionalQuantifier !== true &&
(tests[i].match.static === true ||
prevTest === undefined ||
tests[i].match.fn.test(
prevTest.match.def,
maskset,
pos,
true,
opts
) !== false)
) {
staticAlternations.push(tests[i]);
if (tests[i].match.static === true) prevTest = tests[i];
if (staticAlternations.length > 1) {
if (/[0-9a-bA-Z]/.test(staticAlternations[0].match.def)) {
return opts.placeholder.charAt(pos % opts.placeholder.length);
}
}
}
}
}
}
return test.def;
}
return typeof opts.placeholder === "object"
? test.def
: opts.placeholder.charAt(pos % opts.placeholder.length);
}
// tobe put on prototype?
function getMaskTemplate(
baseOnInput,
minimalPos,
includeMode,
noJit,
clearOptionalTail
) {
// includeMode true => input, undefined => placeholder, false => mask
const inputmask = this,
opts = this.opts,
maskset = this.maskset,
greedy = opts.greedy;
if (clearOptionalTail && opts.greedy) {
opts.greedy = false;
inputmask.maskset.tests = {};
}
minimalPos = minimalPos || 0;
let maskTemplate = [],
ndxIntlzr,
pos = 0,
test,
testPos,
jitRenderStatic;
do {
if (baseOnInput === true && maskset.validPositions[pos]) {
testPos =
clearOptionalTail &&
maskset.validPositions[pos].match.optionality &&
maskset.validPositions[pos + 1] === undefined &&
(maskset.validPositions[pos].generatedInput === true ||
(maskset.validPositions[pos].input ==
opts.skipOptionalPartCharacter &&
pos > 0))
? determineTestTemplate.call(
inputmask,
pos,
getTests.call(inputmask, pos, ndxIntlzr, pos - 1)
)
: maskset.validPositions[pos];
test = testPos.match;
ndxIntlzr = testPos.locator.slice();
maskTemplate.push(
includeMode === true
? testPos.input
: includeMode === false
? test.nativeDef
: getPlaceholder.call(inputmask, pos, test)
);
} else {
testPos = getTestTemplate.call(inputmask, pos, ndxIntlzr, pos - 1);
test = testPos.match;
ndxIntlzr = testPos.locator.slice();
const jitMasking =
noJit === true
? false
: opts.jitMasking !== false
? opts.jitMasking
: test.jit;
// check for groupSeparator is a hack for the numerics as we don't want the render of the groupSeparator beforehand
jitRenderStatic =
(jitRenderStatic ||
maskset.validPositions[
pos - 1
]) /* && getTest.call(inputmask, pos + 1).match.def == "" */ &&
test.static &&
test.def !== opts.groupSeparator &&
test.fn === null;
if (
jitRenderStatic ||
jitMasking === false ||
jitMasking === undefined /* || pos < lvp */ ||
(typeof jitMasking === "number" &&
isFinite(jitMasking) &&
jitMasking > pos)
) {
maskTemplate.push(
includeMode === false
? test.nativeDef
: getPlaceholder.call(inputmask, maskTemplate.length, test)
);
} else {
jitRenderStatic = false;
}
}
pos++;
} while (test.static !== true || test.def !== "" || minimalPos > pos);
if (maskTemplate[maskTemplate.length - 1] === "") {
maskTemplate.pop(); // drop the last one which is empty
}
if (
includeMode !== false || // do not alter the masklength when just retrieving the maskdefinition
maskset.maskLength === undefined
) {
// just make sure the maskLength gets initialized in all cases (needed for isValid)
maskset.maskLength = pos - 1;
}
opts.greedy = greedy;
return maskTemplate;
}
// tobe put on prototype?
function getTestTemplate(pos, ndxIntlzr, tstPs) {
const inputmask = this,
maskset = this.maskset;
return (
maskset.validPositions[pos] ||
determineTestTemplate.call(
inputmask,
pos,
getTests.call(
inputmask,
pos,
ndxIntlzr ? ndxIntlzr.slice() : ndxIntlzr,
tstPs
)
)
);
}
// tobe put on prototype?
function determineTestTemplate(pos, tests) {
let inputmask = this,
opts = this.opts,
lenghtOffset = 0,
optionalityLevel = determineOptionalityLevel(pos, tests);
pos = pos > 0 ? pos - 1 : 0;
let altTest = getTest.call(inputmask, pos),
targetLocator = getLocator(altTest),
tstLocator,
closest,
bestMatch;
if (
opts.greedy &&
tests.length > 1 &&
tests[tests.length - 1].match.def === ""
)
lenghtOffset = 1;
// console.log(" optionality = " + optionalityLevel);
// console.log(" - " + JSON.stringify(tests));
for (let ndx = 0; ndx < tests.length - lenghtOffset; ndx++) {
// find best matching
const tst = tests[ndx];
tstLocator = getLocator(tst, targetLocator.length);
const distance = Math.abs(tstLocator - targetLocator);
if (
tst.unMatchedAlternationStopped !== true ||
tests.filter((tst) => tst.unMatchedAlternationStopped !== true).length <=
1
) {
// only skip when there are choices outside the alternation
if (
closest === undefined ||
(tstLocator !== "" && distance < closest) ||
(bestMatch &&
!opts.greedy &&
bestMatch.match.optionality &&
bestMatch.match.optionality - optionalityLevel > 0 &&
bestMatch.match.newBlockMarker === "master" &&
(!tst.match.optionality ||
tst.match.optionality - optionalityLevel < 1 ||
!tst.match.newBlockMarker)) ||
(bestMatch &&
!opts.greedy &&
bestMatch.match.optionalQuantifier &&
!tst.match.optionalQuantifier)
) {
closest = distance;
bestMatch = tst;
}
}
}
return bestMatch;
}
function determineOptionalityLevel(pos, tests) {
let optionalityLevel = 0,
differentOptionalLevels = false;
tests.forEach((test) => {
if (test.match.optionality) {
if (optionalityLevel !== 0 && optionalityLevel !== test.match.optionality)
differentOptionalLevels = true;
if (optionalityLevel === 0 || optionalityLevel > test.match.optionality) {
optionalityLevel = test.match.optionality;
}
}
});
if (optionalityLevel) {
if (pos == 0) optionalityLevel = 0;
else if (tests.length == 1) optionalityLevel = 0;
else if (!differentOptionalLevels) optionalityLevel = 0;
}
return optionalityLevel;
}
// tobe put on prototype?
function getTest(pos, tests) {
const inputmask = this,
maskset = this.maskset;
if (maskset.validPositions[pos]) {
return maskset.validPositions[pos];
}
return (tests || getTests.call(inputmask, pos))[0];
}
function isSubsetOf(source, target, opts) {
function expand(pattern) {
let expanded = [],
start = -1,
end;
for (let i = 0, l = pattern.length; i < l; i++) {
if (pattern.charAt(i) === "-") {
end = pattern.charCodeAt(i + 1);
while (++start < end) expanded.push(String.fromCharCode(start));
} else {
start = pattern.charCodeAt(i);
expanded.push(pattern.charAt(i));
}
}
return expanded.join("");
}
if (source.match.def === target.match.nativeDef) return true;
if (
(opts.regex ||
(source.match.fn instanceof RegExp &&
target.match.fn instanceof RegExp)) &&
source.match.static !== true &&
target.match.static !== true
) {
// is regex a subset
if (target.match.fn.source === ".") return true;
return (
expand(target.match.fn.source.replace(/[[\]/]/g, "")).indexOf(
expand(source.match.fn.source.replace(/[[\]/]/g, ""))
) !== -1
);
}
return false;
}
// tobe put on prototype?
function getTests(pos, ndxIntlzr, tstPs) {
let inputmask = this,
$ = this.dependencyLib,
maskset = this.maskset,
opts = this.opts,
el = this.el,
maskTokens = maskset.maskToken,
testPos = ndxIntlzr ? tstPs : 0,
ndxInitializer = ndxIntlzr ? ndxIntlzr.slice() : [0],
matches = [],
insertStop = false,
latestMatch,
cacheDependency = ndxIntlzr ? ndxIntlzr.join("") : "",
unMatchedAlternation = false;
function resolveTestFromToken(
maskToken,
ndxInitializer,
loopNdx,
quantifierRecurse
) {
// ndxInitializer contains a set of indexes to speedup searches in the mtokens
function handleMatch(match, loopNdx, quantifierRecurse) {
function isFirstMatch(latestMatch, tokenGroup) {
let firstMatch = tokenGroup.matches.indexOf(latestMatch) === 0;
if (!firstMatch) {
tokenGroup.matches.every(function (match, ndx) {
if (match.isQuantifier === true) {
firstMatch = isFirstMatch(
latestMatch,
tokenGroup.matches[ndx - 1]
);
} else if (Object.prototype.hasOwnProperty.call(match, "matches"))
firstMatch = isFirstMatch(latestMatch, match);
if (firstMatch) return false;
return true;
});
}
return firstMatch;
}
function resolveNdxInitializer(pos, alternateNdx, targetAlternation) {
let bestMatch, indexPos;
if (maskset.tests[pos] || maskset.validPositions[pos]) {
(maskset.validPositions[pos]
? [maskset.validPositions[pos]]
: maskset.tests[pos]
).every(function (lmnt, ndx) {
if (lmnt.mloc[alternateNdx]) {
bestMatch = lmnt;
return false; // break
}
const alternation =
targetAlternation !== undefined
? targetAlternation
: lmnt.alternation,
ndxPos =
lmnt.locator[alternation] !== undefined
? lmnt.locator[alternation].toString().indexOf(alternateNdx)
: -1;
if (
(indexPos === undefined || ndxPos < indexPos) &&
ndxPos !== -1
) {
bestMatch = lmnt;
indexPos = ndxPos;
}
return true;
});
}
if (bestMatch) {
const bestMatchAltIndex = bestMatch.locator[bestMatch.alternation],
locator =
bestMatch.mloc[alternateNdx] ||
bestMatch.mloc[bestMatchAltIndex] ||
bestMatch.locator;
if (locator[locator.length - 1].toString().indexOf(":") !== -1) {
// eslint-disable-next-line no-unused-vars
const alternation = locator.pop();
// targetAlternation = parseInt(alternation.substring(1));
}
return locator.slice(
(targetAlternation !== undefined
? targetAlternation
: bestMatch.alternation) + 1
);
} else {
return targetAlternation !== undefined
? resolveNdxInitializer(pos, alternateNdx)
: undefined;
}
}
function staticCanMatchDefinition(source, target) {
return source.match.static === true && target.match.static !== true
? target.match.fn.test(
source.match.def,
maskset,
pos,
false,
opts,
false
)
: false;
}
// mergelocators for retrieving the correct locator match when merging
function setMergeLocators(targetMatch, altMatch) {
function mergeLoc(altNdx) {
targetMatch.mloc = targetMatch.mloc || {};
let locNdx = targetMatch.locator[altNdx];
if (locNdx === undefined) {
targetMatch.alternation = undefined;
} else {
if (typeof locNdx === "string") locNdx = locNdx.split(",")[0];
if (targetMatch.mloc[locNdx] === undefined) {
targetMatch.mloc[locNdx] = targetMatch.locator.slice();
targetMatch.mloc[locNdx].push(`:${targetMatch.alternation}`); // add alternation index
}
if (altMatch !== undefined) {
const offset = 0;
for (let ndx in altMatch.mloc) {
if (typeof ndx === "string") ndx = parseInt(ndx.split(",")[0]);
// do {
// if (targetMatch.mloc[ndx + offset] === undefined) {
targetMatch.mloc[ndx + offset] = altMatch.mloc[ndx];
// break;
// }
// } while (targetMatch.mloc[ndx + offset++] !== undefined);
}
targetMatch.locator[altNdx] = Object.keys(targetMatch.mloc).join(
","
);
}
if (targetMatch.alternation > altNdx) {
// if the alternation index is higher than the current one resolve it to the alternation
targetMatch.alternation = altNdx;
}
return true;
}
return false;
}
let alternationNdx = targetMatch.alternation,
shouldMerge =
altMatch === undefined ||
(alternationNdx <= altMatch.alternation &&
targetMatch.locator[alternationNdx]
.toString()
.indexOf(altMatch.locator[alternationNdx]) === -1);
if (!shouldMerge && alternationNdx > altMatch.alternation) {
for (let i = 0; i < alternationNdx; i++) {
if (targetMatch.locator[i] !== altMatch.locator[i]) {
alternationNdx = i;
shouldMerge = true;
break;
}
}
}
if (shouldMerge) {
return mergeLoc(alternationNdx);
}
return false;
}
function isSameLevel(targetMatch, altMatch) {
if (targetMatch.locator.length !== altMatch.locator.length) {
return false;
}
for (
let locNdx = targetMatch.alternation + 1;
locNdx < targetMatch.locator.length;
locNdx++
) {
if (targetMatch.locator[locNdx] !== altMatch.locator[locNdx]) {
return false;
}
}
return true;
}
function handleGroup() {
match = handleMatch(
maskToken.matches[maskToken.matches.indexOf(match) + 1],
loopNdx,
quantifierRecurse
);
if (match) return true;
}
function handleOptional() {
const optionalToken = match,
mtchsNdx = matches.length;
match = resolveTestFromToken(
match,
ndxInitializer,
loopNdx,
quantifierRecurse
);
if (matches.length > 0) {
// check on matches.length instead of match to handle quantifier in a recursive call
// mark optionality in matches
matches.forEach(function (mtch, ndx) {
if (ndx >= mtchsNdx) {
mtch.match.optionality = mtch.match.optionality
? mtch.match.optionality + 1
: 1;
}
});
latestMatch = matches[matches.length - 1].match;
if (
quantifierRecurse === undefined &&
isFirstMatch(latestMatch, optionalToken)
) {
// prevent loop see #698
insertStop = true; // insert a stop
testPos = pos; // match the position after the group
} else {
return match; // make the loop continue when it is deliberately by a quantifier
}
}
}
function handleAlternator() {
function isUnmatchedAlternation(alternateToken) {
let matchesLength = alternateToken.matches[0].matches
? alternateToken.matches[0].matches.length
: 1,
matchesNewLength;
for (let alndx = 0; alndx < alternateToken.matches.length; alndx++) {
matchesNewLength = alternateToken.matches[alndx].matches
? alternateToken.matches[alndx].matches.length
: 1;
if (matchesLength !== matchesNewLength) {
break;
}
}
return matchesLength !== matchesNewLength;
}
inputmask.hasAlternator = true;
let alternateToken = match,
malternateMatches = [],
maltMatches,
currentMatches = matches.slice(),
loopNdxCnt = loopNdx.length,
altIndex = ndxInitializer.length > 0 ? ndxInitializer.shift() : -1;
if (altIndex === -1 || typeof altIndex === "string") {
let currentPos = testPos,
ndxInitializerClone = ndxInitializer.slice(),
altIndexArr = [],
amndx;
if (typeof altIndex === "string") {
altIndexArr = altIndex.split(",");
} else {
for (amndx = 0; amndx < alternateToken.matches.length; amndx++) {
altIndexArr.push(amndx.toString());
}
}
if (maskset.excludes[pos] !== undefined) {
const altIndexArrClone = altIndexArr.slice();
for (let i = 0, exl = maskset.excludes[pos].length; i < exl; i++) {
const excludeSet = maskset.excludes[pos][i].toString().split(":");
if (loopNdx.length == excludeSet[1]) {
altIndexArr.splice(altIndexArr.indexOf(excludeSet[0]), 1);
}
}
if (altIndexArr.length === 0) {
// fully alternated => reset
delete maskset.excludes[pos];
altIndexArr = altIndexArrClone;
}
}
if (
opts.keepStatic === true ||
(isFinite(parseInt(opts.keepStatic)) &&
currentPos >= opts.keepStatic)
)
altIndexArr = altIndexArr.slice(0, 1);
for (let ndx = 0; ndx < altIndexArr.length; ndx++) {
amndx = parseInt(altIndexArr[ndx]);
matches = [];
// set the correct ndxInitializer
ndxInitializer =
typeof altIndex === "string"
? resolveNdxInitializer(testPos, amndx, loopNdxCnt) ||
ndxInitializerClone.slice()
: ndxInitializerClone.slice();
// console.log("ndxInit", ndxInitializer);
const tokenMatch = alternateToken.matches[amndx];
if (
tokenMatch &&
handleMatch(
tokenMatch,
[amndx].concat(loopNdx),
quantifierRecurse
)
) {
match = true;
} else {
if (ndx === 0) {
unMatchedAlternation = isUnmatchedAlternation(alternateToken);
}
if (
tokenMatch &&
tokenMatch.matches &&
tokenMatch.matches.length >
alternateToken.matches[0].matches.length
) {
break;
}
}
maltMatches = matches.slice();
testPos = currentPos;
matches = [];
// fuzzy merge matches
for (let ndx1 = 0; ndx1 < maltMatches.length; ndx1++) {
let altMatch = maltMatches[ndx1],
dropMatch = false;
altMatch.alternation = altMatch.alternation || loopNdxCnt;
setMergeLocators(altMatch);
for (let ndx2 = 0; ndx2 < malternateMatches.length; ndx2++) {
const altMatch2 = malternateMatches[ndx2];
if (
typeof altIndex !== "string" ||
(altMatch.alternation !== undefined &&
altIndexArr.includes(
altMatch.locator[altMatch.alternation].toString()
))
) {
if (altMatch.match.nativeDef === altMatch2.match.nativeDef) {
dropMatch = true;
setMergeLocators(altMatch2, altMatch);
break;
} else if (isSubsetOf(altMatch, altMatch2, opts)) {
if (setMergeLocators(altMatch, altMatch2)) {
dropMatch = true;
malternateMatches.splice(
malternateMatches.indexOf(altMatch2),
0,
altMatch
);
}
break;
} else if (isSubsetOf(altMatch2, altMatch, opts)) {
setMergeLocators(altMatch2, altMatch);
break;
} else if (staticCanMatchDefinition(altMatch, altMatch2)) {
if (
!isSameLevel(altMatch, altMatch2) &&
el.inputmask.userOptions.keepStatic === undefined
) {
opts.keepStatic = true;
} else if (setMergeLocators(altMatch, altMatch2)) {
// insert match above general match
dropMatch = true;
malternateMatches.splice(
malternateMatches.indexOf(altMatch2),
0,
altMatch
);
}
break;
} else if (staticCanMatchDefinition(altMatch2, altMatch)) {
setMergeLocators(altMatch2, altMatch);
break;
}
}
}
if (!dropMatch) {
malternateMatches.push(altMatch);
}
}
}
matches = currentMatches.concat(malternateMatches);
testPos = pos;
insertStop = matches.length > 0 && unMatchedAlternation; // insert a stopelemnt when there is an alternate - needed for non-greedy option
match = malternateMatches.length > 0 && !unMatchedAlternation; // set correct match state
if (unMatchedAlternation && insertStop && !match) {
// mark matches with unMatchedAlternationStopped
matches.forEach(function (mtch, ndx) {
mtch.unMatchedAlternationStopped = true;
});
}
// cloneback
ndxInitializer = ndxInitializerClone.slice();
} else {
match = handleMatch(
alternateToken.matches[altIndex] || maskToken.matches[altIndex],
[altIndex].concat(loopNdx),
quantifierRecurse
);
}
if (match) return true;
}
function handleQuantifier() {
let qt = match,
breakloop = false;
for (
var qndx = ndxInitializer.length > 0 ? ndxInitializer.shift() : 0;
qndx < (isNaN(qt.quantifier.max) ? qndx + 1 : qt.quantifier.max) &&
testPos <= pos;
qndx++
) {
var tokenGroup = maskToken.matches[maskToken.matches.indexOf(qt) - 1];
match = handleMatch(tokenGroup, [qndx].concat(loopNdx), tokenGroup); // set the tokenGroup as quantifierRecurse marker
if (match) {
matches.forEach(function (mtch, ndx) {
if (IsMatchOf(tokenGroup, mtch.match)) latestMatch = mtch.match;
else latestMatch = matches[matches.length - 1].match;
// mark optionality
// TODO FIX RECURSIVE QUANTIFIERS
latestMatch.optionalQuantifier = qndx >= qt.quantifier.min;
// console.log(pos + " " + qt.quantifier.min + " " + latestMatch.optionalQuantifier);
// qndx + 1 as the index starts from 0
latestMatch.jit =
(qndx + 1) * (tokenGroup.matches.indexOf(latestMatch) + 1) >
qt.quantifier.jit;
if (
latestMatch.optionalQuantifier &&
isFirstMatch(latestMatch, tokenGroup)
) {
insertStop = true;
testPos = pos; // match the position after the group
if (
opts.greedy &&
maskset.validPositions[pos - 1] == undefined &&
qndx > qt.quantifier.min &&
["*", "+"].indexOf(qt.quantifier.max) != -1
) {
matches.pop();
cacheDependency = undefined;
}
breakloop = true; // stop quantifierloop && search for next possible match
match = false; // mark match to false to make sure the loop in optionals continues
}
if (
!breakloop &&
latestMatch.jit /* && !latestMatch.optionalQuantifier */
) {
// always set jitOffset, isvalid checks when to apply
maskset.jitOffset[pos] =
tokenGroup.matches.length -
tokenGroup.matches.indexOf(latestMatch);
}
});
if (breakloop) break; // search for next possible match
return true;
}
}
}
if (testPos > pos + opts._maxTestPos) {
throw new Error(
`Inputmask: There is probably an error in your mask definition or in the code. Create an issue on github with an example of the mask you are using. ${maskset.mask}`
);
}
if (testPos === pos && match.matches === undefined) {
matches.push({
match,
locator: loopNdx.reverse(),
cd: cacheDependency,
mloc: {}
});
if (
match.optionality &&
quantifierRecurse === undefined &&
((opts.definitions &&
opts.definitions[match.nativeDef] &&
opts.definitions[match.nativeDef].optional) ||
(Inputmask.prototype.definitions[match.nativeDef] &&
Inputmask.prototype.definitions[match.nativeDef].optional))
) {
// prevent loop see #698
insertStop = true; // insert a stop
testPos = pos; // match the position after the group
} else {
return true;
}
} else if (match.matches !== undefined) {
if (match.isGroup && quantifierRecurse !== match) {
// when a group pass along to the quantifier
return handleGroup();
} else if (match.isOptional) {
return handleOptional();
} else if (match.isAlternator) {
return handleAlternator();
} else if (
match.isQuantifier &&
quantifierRecurse !==
maskToken.matches[maskToken.matches.indexOf(match) - 1]
) {
return handleQuantifier();
} else {
match = resolveTestFromToken(
match,
ndxInitializer,
loopNdx,
quantifierRecurse
);
if (match) return true;
}
} else {
testPos++;
}
}
// the offset is set in the quantifierloop when git masking is used
for (
let tndx = ndxInitializer.length > 0 ? ndxInitializer.shift() : 0;
tndx < maskToken.matches.length;
tndx++
) {
if (maskToken.matches[tndx].isQuantifier !== true) {
const match = handleMatch(
maskToken.matches[tndx],
[tndx].concat(loopNdx),
quantifierRecurse
);
if (match && testPos === pos) {
return match;
} else if (testPos > pos) {
break;
}
}
}
}
function IsMatchOf(tokenGroup, match) {
let isMatch = tokenGroup.matches.indexOf(match) != -1;
if (!isMatch) {
tokenGroup.matches.forEach((mtch, ndx) => {
if (mtch.matches !== undefined && !isMatch) {
isMatch = IsMatchOf(mtch, match);
}
});
}
return isMatch;
}
function mergeLocators(pos, tests) {
let locator = [],
alternation;
if (!Array.isArray(tests)) tests = [tests];
if (tests.length > 0) {
if (tests[0].alternation === undefined || opts.keepStatic === true) {
locator = determineTestTemplate
.call(inputmask, pos, tests.slice())
.locator.slice();
if (locator.length === 0) locator = tests[0].locator.slice();
} else {
tests.forEach(function (tst) {
if (tst.def !== "") {
if (locator.length === 0) {
alternation = tst.alternation;
locator = tst.locator.slice();
} else {
if (
tst.locator[alternation] &&
locator[alternation]
.toString()
.indexOf(tst.locator[alternation]) === -1
) {
locator[alternation] += "," + tst.locator[alternation];
}
}
}
});
}
}
return locator;
}
if (pos > -1) {
if (ndxIntlzr === undefined) {
// determine index initializer
let previousPos = pos - 1,
test;
while (
(test =
maskset.validPositions[previousPos] || maskset.tests[previousPos]) ===
undefined &&
previousPos > -1
) {
previousPos--;
}
if (test !== undefined && previousPos > -1) {
ndxInitializer = mergeLocators(previousPos, test);
cacheDependency = ndxInitializer.join("");
testPos = previousPos;
}
}
if (maskset.tests[pos] && maskset.tests[pos][0].cd === cacheDependency) {
// cacheDependency is set on all tests, just check on the first
return maskset.tests[pos];
}
for (
let mtndx = ndxInitializer.shift();
mtndx < maskTokens.length;
mtndx++
) {
const match = resolveTestFromToken(maskTokens[mtndx], ndxInitializer, [
mtndx
]);
if ((match && testPos === pos) || testPos > pos) {
break;
}
}
}
if (matches.length === 0 || insertStop) {
matches.push({
match: {
fn: null,
static: true,
optionality: false,
casing: null,
def: "",
placeholder: ""
},
// mark when there are unmatched alternations ex: mask: "(a|aa)"
// this will result in the least distance to select the correct test result in determineTestTemplate
locator:
unMatchedAlternation &&
matches.filter((tst) => tst.unMatchedAlternationStopped !== true)
.length === 0
? [0]
: [],
mloc: {},
cd: cacheDependency
});
}
let result;
if (ndxIntlzr !== undefined && maskset.tests[pos]) {
// prioritize full tests for caching
result = $.extend(true, [], matches);
} else {
// console.log("stored " + pos + " - " + JSON.stringify(matches));
maskset.tests[pos] = $.extend(true, [], matches); // set a clone to prevent overwriting some props
result = maskset.tests[pos];
}
// console.log(pos + " - " + JSON.stringify(matches));
// cleanup optionality marking
matches.forEach((t) => {
t.match.optionality = t.match.defOptionality || false;
});
return result;
}