170 lines
9.2 KiB
JavaScript
170 lines
9.2 KiB
JavaScript
/*
|
|
Input Mask plugin extensions
|
|
http://github.com/RobinHerbots/jquery.inputmask
|
|
Copyright (c) 2010 - 2014 Robin Herbots
|
|
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
|
|
Version: 0.0.0
|
|
|
|
Regex extensions on the jquery.inputmask base
|
|
Allows for using regular expressions as a mask
|
|
*/
|
|
(function ($) {
|
|
$.extend($.inputmask.defaults.aliases, { // $(selector).inputmask("Regex", { regex: "[0-9]*"}
|
|
'Regex': {
|
|
mask: "r",
|
|
greedy: false,
|
|
repeat: "*",
|
|
regex: null,
|
|
regexTokens: null,
|
|
//Thx to https://github.com/slevithan/regex-colorizer for the tokenizer regex
|
|
tokenizer: /\[\^?]?(?:[^\\\]]+|\\[\S\s]?)*]?|\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\S\s]?)|\((?:\?[:=!]?)?|(?:[?*+]|\{[0-9]+(?:,[0-9]*)?\})\??|[^.?*+^${[()|\\]+|./g,
|
|
quantifierFilter: /[0-9]+[^,]/,
|
|
definitions: {
|
|
'r': {
|
|
validator: function (chrs, buffer, pos, strict, opts) {
|
|
function regexToken() {
|
|
this.matches = [];
|
|
this.isGroup = false;
|
|
this.isQuantifier = false;
|
|
this.isLiteral = false;
|
|
}
|
|
function analyseRegex() {
|
|
var currentToken = new regexToken(), match, m, opengroups = [];
|
|
|
|
opts.regexTokens = [];
|
|
|
|
// The tokenizer regex does most of the tokenization grunt work
|
|
while (match = opts.tokenizer.exec(opts.regex)) {
|
|
m = match[0];
|
|
switch (m.charAt(0)) {
|
|
case "[": // Character class
|
|
case "\\": // Escape or backreference
|
|
if (opengroups.length > 0) {
|
|
opengroups[opengroups.length - 1]["matches"].push(m);
|
|
} else {
|
|
currentToken.matches.push(m);
|
|
}
|
|
break;
|
|
case "(": // Group opening
|
|
if (!currentToken.isGroup && currentToken.matches.length > 0)
|
|
opts.regexTokens.push(currentToken);
|
|
currentToken = new regexToken();
|
|
currentToken.isGroup = true;
|
|
opengroups.push(currentToken);
|
|
break;
|
|
case ")": // Group closing
|
|
var groupToken = opengroups.pop();
|
|
if (opengroups.length > 0) {
|
|
opengroups[opengroups.length - 1]["matches"].push(groupToken);
|
|
} else {
|
|
opts.regexTokens.push(groupToken);
|
|
currentToken = new regexToken();
|
|
}
|
|
break;
|
|
case "{": //Quantifier
|
|
var quantifier = new regexToken();
|
|
quantifier.isQuantifier = true;
|
|
quantifier.matches.push(m);
|
|
if (opengroups.length > 0) {
|
|
opengroups[opengroups.length - 1]["matches"].push(quantifier);
|
|
} else {
|
|
currentToken.matches.push(quantifier);
|
|
}
|
|
break;
|
|
default:
|
|
// Vertical bar (alternator)
|
|
// ^ or $ anchor
|
|
// Dot (.)
|
|
// Literal character sequence
|
|
var literal = new regexToken();
|
|
literal.isLiteral = true;
|
|
literal.matches.push(m);
|
|
if (opengroups.length > 0) {
|
|
opengroups[opengroups.length - 1]["matches"].push(literal);
|
|
} else {
|
|
currentToken.matches.push(literal);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (currentToken.matches.length > 0)
|
|
opts.regexTokens.push(currentToken);
|
|
}
|
|
function validateRegexToken(token, fromGroup) {
|
|
var isvalid = false;
|
|
if (fromGroup) {
|
|
regexPart += "(";
|
|
openGroupCount++;
|
|
}
|
|
for (var mndx = 0; mndx < token["matches"].length; mndx++) {
|
|
var matchToken = token["matches"][mndx];
|
|
if (matchToken["isGroup"] == true) {
|
|
isvalid = validateRegexToken(matchToken, true);
|
|
} else if (matchToken["isQuantifier"] == true) {
|
|
matchToken = matchToken["matches"][0];
|
|
var quantifierMax = opts.quantifierFilter.exec(matchToken)[0].replace("}", "");
|
|
var testExp = regexPart + "{1," + quantifierMax + "}"; //relax quantifier validation
|
|
for (var j = 0; j < openGroupCount; j++) {
|
|
testExp += ")";
|
|
}
|
|
var exp = new RegExp("^(" + testExp + ")$");
|
|
isvalid = exp.test(bufferStr);
|
|
regexPart += matchToken;
|
|
} else if (matchToken["isLiteral"] == true) {
|
|
matchToken = matchToken["matches"][0];
|
|
var testExp = regexPart, openGroupCloser = "";
|
|
for (var j = 0; j < openGroupCount; j++) {
|
|
openGroupCloser += ")";
|
|
}
|
|
for (var k = 0; k < matchToken.length; k++) { //relax literal validation
|
|
testExp = (testExp + matchToken[k]).replace(/\|$/, "");
|
|
var exp = new RegExp("^(" + testExp + openGroupCloser + ")$");
|
|
isvalid = exp.test(bufferStr);
|
|
if (isvalid) break;
|
|
}
|
|
regexPart += matchToken;
|
|
//console.log(bufferStr + " " + exp + " " + isvalid);
|
|
} else {
|
|
regexPart += matchToken;
|
|
var testExp = regexPart.replace(/\|$/, "");
|
|
for (var j = 0; j < openGroupCount; j++) {
|
|
testExp += ")";
|
|
}
|
|
var exp = new RegExp("^(" + testExp + ")$");
|
|
isvalid = exp.test(bufferStr);
|
|
//console.log(bufferStr + " " + exp + " " + isvalid);
|
|
}
|
|
if (isvalid) break;
|
|
}
|
|
|
|
if (fromGroup) {
|
|
regexPart += ")";
|
|
openGroupCount--;
|
|
}
|
|
|
|
return isvalid;
|
|
}
|
|
|
|
|
|
if (opts.regexTokens == null) {
|
|
analyseRegex();
|
|
}
|
|
|
|
var cbuffer = buffer.slice(), regexPart = "", isValid = false, openGroupCount = 0;
|
|
cbuffer.splice(pos, 0, chrs);
|
|
var bufferStr = cbuffer.join('');
|
|
for (var i = 0; i < opts.regexTokens.length; i++) {
|
|
var regexToken = opts.regexTokens[i];
|
|
isValid = validateRegexToken(regexToken, regexToken["isGroup"]);
|
|
if (isValid) break;
|
|
}
|
|
|
|
return isValid;
|
|
},
|
|
cardinality: 1
|
|
}
|
|
}
|
|
}
|
|
});
|
|
})(jQuery);
|