inputmask
Advanced tools
Comparing version 5.0.9-beta.62 to 5.0.9-beta.70
@@ -12,2 +12,2 @@ import "./lib/polyfills/Object.getPrototypeOf"; | ||
export default Inputmask; | ||
export default Inputmask; |
@@ -12,3 +12,4 @@ # Change Log | ||
- datetime alias | ||
- add support for mmm & mmmm #2751 (WIP) | ||
- add support for mmm & mmmm #2751 | ||
- add custom placeholder support | ||
- Update IP extension to support greedy option. #2749 | ||
@@ -19,2 +20,5 @@ - Properly handle insertMode false in alternation logic. | ||
### Fixed | ||
- Poor performance on decimal input mask #1505 | ||
- TypeError: Cannot read properties of null (reading 'charAt') at m.onBeforeMask #2789 | ||
- Cursor moves to start when there is a 0 in the decimal, How to stop this behavior? #2784 | ||
- Unexpected character removed #2765 | ||
@@ -21,0 +25,0 @@ - d/mm/yyyy is converted to d/m//yyyd #2394 |
@@ -8,20 +8,25 @@ /* | ||
(function (factory) { | ||
factory(jQuery, window.Inputmask, window); | ||
} | ||
(function ($, Inputmask, window) { | ||
$(window.document).ajaxComplete(function (event, xmlHttpRequest, ajaxOptions) { | ||
if ($.inArray("html", ajaxOptions.dataTypes) !== -1) { | ||
$(".inputmask, [data-inputmask], [data-inputmask-mask], [data-inputmask-alias], [data-inputmask-regex]").each(function (ndx, lmnt) { | ||
if (lmnt.inputmask === undefined) { | ||
Inputmask().mask(lmnt); | ||
} | ||
}); | ||
} | ||
}).ready(function () { | ||
$(".inputmask, [data-inputmask], [data-inputmask-mask], [data-inputmask-alias],[data-inputmask-regex]").each(function (ndx, lmnt) { | ||
if (lmnt.inputmask === undefined) { | ||
Inputmask().mask(lmnt); | ||
} | ||
}); | ||
}); | ||
})); | ||
factory(jQuery, window.Inputmask, window); | ||
})(function ($, Inputmask, window) { | ||
$(window.document) | ||
.ajaxComplete(function (event, xmlHttpRequest, ajaxOptions) { | ||
if ($.inArray("html", ajaxOptions.dataTypes) !== -1) { | ||
$( | ||
".inputmask, [data-inputmask], [data-inputmask-mask], [data-inputmask-alias], [data-inputmask-regex]" | ||
).each(function (ndx, lmnt) { | ||
if (lmnt.inputmask === undefined) { | ||
Inputmask().mask(lmnt); | ||
} | ||
}); | ||
} | ||
}) | ||
.ready(function () { | ||
$( | ||
".inputmask, [data-inputmask], [data-inputmask-mask], [data-inputmask-alias],[data-inputmask-regex]" | ||
).each(function (ndx, lmnt) { | ||
if (lmnt.inputmask === undefined) { | ||
Inputmask().mask(lmnt); | ||
} | ||
}); | ||
}); | ||
}); |
@@ -0,1 +1,2 @@ | ||
// eslint-disable-next-line import/no-unresolved | ||
import "./inputmask.js"; | ||
@@ -5,2 +6,2 @@ | ||
window.Inputmask = undefined; | ||
export default inputmask; | ||
export default inputmask; |
@@ -8,20 +8,25 @@ /* | ||
(function (factory) { | ||
factory(jQuery, window.Inputmask, window); | ||
} | ||
(function ($, Inputmask, window) { | ||
$(window.document).ajaxComplete(function (event, xmlHttpRequest, ajaxOptions) { | ||
if ($.inArray("html", ajaxOptions.dataTypes) !== -1) { | ||
$(".inputmask, [data-inputmask], [data-inputmask-mask], [data-inputmask-alias], [data-inputmask-regex]").each(function (ndx, lmnt) { | ||
if (lmnt.inputmask === undefined) { | ||
Inputmask().mask(lmnt); | ||
} | ||
}); | ||
} | ||
}).ready(function () { | ||
$(".inputmask, [data-inputmask], [data-inputmask-mask], [data-inputmask-alias],[data-inputmask-regex]").each(function (ndx, lmnt) { | ||
if (lmnt.inputmask === undefined) { | ||
Inputmask().mask(lmnt); | ||
} | ||
}); | ||
}); | ||
})); | ||
factory(jQuery, window.Inputmask, window); | ||
})(function ($, Inputmask, window) { | ||
$(window.document) | ||
.ajaxComplete(function (event, xmlHttpRequest, ajaxOptions) { | ||
if ($.inArray("html", ajaxOptions.dataTypes) !== -1) { | ||
$( | ||
".inputmask, [data-inputmask], [data-inputmask-mask], [data-inputmask-alias], [data-inputmask-regex]" | ||
).each(function (ndx, lmnt) { | ||
if (lmnt.inputmask === undefined) { | ||
Inputmask().mask(lmnt); | ||
} | ||
}); | ||
} | ||
}) | ||
.ready(function () { | ||
$( | ||
".inputmask, [data-inputmask], [data-inputmask-mask], [data-inputmask-alias],[data-inputmask-regex]" | ||
).each(function (ndx, lmnt) { | ||
if (lmnt.inputmask === undefined) { | ||
Inputmask().mask(lmnt); | ||
} | ||
}); | ||
}); | ||
}); |
@@ -0,1 +1,2 @@ | ||
// eslint-disable-next-line import/no-unresolved | ||
import "./inputmask.js"; | ||
@@ -5,2 +6,2 @@ | ||
window.Inputmask = undefined; | ||
export default inputmask; | ||
export default inputmask; |
@@ -1,69 +0,64 @@ | ||
import {keys} from "./keycode.js"; | ||
export default { | ||
_maxTestPos: 500, | ||
placeholder: "_", | ||
optionalmarker: ["[", "]"], | ||
quantifiermarker: ["{", "}"], | ||
groupmarker: ["(", ")"], | ||
alternatormarker: "|", | ||
escapeChar: "\\", | ||
mask: null, //needs tobe null instead of undefined as the extend method does not consider props with the undefined value | ||
regex: null, //regular expression as a mask | ||
oncomplete: () => { | ||
}, //executes when the mask is complete | ||
onincomplete: () => { | ||
}, //executes when the mask is incomplete and focus is lost | ||
oncleared: () => { | ||
}, //executes when the mask is cleared | ||
repeat: 0, //repetitions of the mask: * ~ forever, otherwise specify an integer | ||
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, | ||
insertMode: true, //insert the input or overwrite the input | ||
insertModeVisual: true, //show selected caret when insertmode = false | ||
clearIncomplete: false, //clear the incomplete input on blur | ||
alias: null, | ||
onKeyDown: () => { | ||
}, //callback to implement autocomplete on certain keys for example. args => event, buffer, caretPos, opts | ||
onBeforeMask: null, //executes before masking the initial value to allow preprocessing of the initial value. args => initialValue, opts => return processedValue | ||
onBeforePaste: function (pastedValue, opts) { | ||
return typeof opts.onBeforeMask === "function" ? opts.onBeforeMask.call(this, pastedValue, opts) : pastedValue; | ||
}, //executes before masking the pasted value to allow preprocessing of the pasted value. args => pastedValue, opts => return processedValue | ||
onBeforeWrite: null, //executes before writing to the masked element. args => event, opts | ||
onUnMask: null, //executes after unmasking to allow postprocessing of the unmaskedvalue. args => maskedValue, unmaskedValue, opts | ||
showMaskOnFocus: true, //show the mask-placeholder when the input has focus | ||
showMaskOnHover: true, //show the mask-placeholder when hovering the empty input | ||
onKeyValidation: () => { | ||
}, //executes on every key-press with the result of isValid. Params: key, result, opts | ||
skipOptionalPartCharacter: " ", //a character which can be used to skip an optional part of a mask | ||
numericInput: false, //numericInput input direction style (input shifts to the left while holding the caret position) | ||
rightAlign: false, //align to the right | ||
undoOnEscape: true, //pressing escape reverts the value to the value before focus | ||
//numeric basic properties | ||
radixPoint: "", //".", // | "," | ||
_radixDance: false, //dance around the radixPoint | ||
groupSeparator: "", //",", // | "." | ||
//numeric basic properties | ||
keepStatic: null, //try to keep the mask static while typing. Decisions to alter the mask will be posponed if possible | ||
positionCaretOnTab: true, //when enabled the caret position is set after the latest valid position on TAB | ||
tabThrough: false, //allows for tabbing through the different parts of the masked field | ||
supportsInputType: ["text", "tel", "url", "password", "search"], //list with the supported input types | ||
isComplete: null, //override for isComplete - args => buffer, opts - return true || false | ||
preValidation: null, //hook to preValidate the input. Usefull for validating regardless the definition. args => buffer, pos, char, isSelection, opts, maskset, caretPos, strict => return true/false/command object | ||
postValidation: null, //hook to postValidate the result from isValid. Usefull for validating the entry as a whole. args => buffer, pos, c, currentResult, opts, maskset, strict, fromCheckval => return true/false/json | ||
staticDefinitionSymbol: undefined, //specify a definitionSymbol for static content, used to make matches for alternators | ||
jitMasking: false, //just in time masking ~ only mask while typing, can n (number), true or false | ||
nullable: true, //return nothing instead of the buffertemplate when the user hasn't entered anything. | ||
inputEventOnly: false, //dev option - testing inputfallback behavior | ||
noValuePatching: false, //disable value property patching | ||
positionCaretOnClick: "lvp", //none, lvp (based on the last valid position (default), radixFocus (position caret to radixpoint on initial click), select (select the whole input), ignore (ignore the click and continue the mask) | ||
casing: null, //mask-level casing. Options: null, "upper", "lower" or "title" or callback args => elem, test, pos, validPositions return charValue | ||
inputmode: "text", //specify the inputmode | ||
importDataAttributes: true, //import data-inputmask attributes | ||
shiftPositions: true, //shift position of the mask entries on entry and deletion. | ||
usePrototypeDefinitions: true, //use the default defined definitions from the prototype | ||
validationEventTimeOut: 3000, //Time to show validation error on form submit | ||
substitutes: {} //define character substitutes | ||
_maxTestPos: 500, | ||
placeholder: "_", | ||
optionalmarker: ["[", "]"], | ||
quantifiermarker: ["{", "}"], | ||
groupmarker: ["(", ")"], | ||
alternatormarker: "|", | ||
escapeChar: "\\", | ||
mask: null, // needs tobe null instead of undefined as the extend method does not consider props with the undefined value | ||
regex: null, // regular expression as a mask | ||
oncomplete: () => {}, // executes when the mask is complete | ||
onincomplete: () => {}, // executes when the mask is incomplete and focus is lost | ||
oncleared: () => {}, // executes when the mask is cleared | ||
repeat: 0, // repetitions of the mask: * ~ forever, otherwise specify an integer | ||
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, | ||
insertMode: true, // insert the input or overwrite the input | ||
insertModeVisual: true, // show selected caret when insertmode = false | ||
clearIncomplete: false, // clear the incomplete input on blur | ||
alias: null, | ||
onKeyDown: () => {}, // callback to implement autocomplete on certain keys for example. args => event, buffer, caretPos, opts | ||
onBeforeMask: null, // executes before masking the initial value to allow preprocessing of the initial value. args => initialValue, opts => return processedValue | ||
onBeforePaste: function (pastedValue, opts) { | ||
return typeof opts.onBeforeMask === "function" | ||
? opts.onBeforeMask.call(this, pastedValue, opts) | ||
: pastedValue; | ||
}, // executes before masking the pasted value to allow preprocessing of the pasted value. args => pastedValue, opts => return processedValue | ||
onBeforeWrite: null, // executes before writing to the masked element. args => event, opts | ||
onUnMask: null, // executes after unmasking to allow postprocessing of the unmaskedvalue. args => maskedValue, unmaskedValue, opts | ||
showMaskOnFocus: true, // show the mask-placeholder when the input has focus | ||
showMaskOnHover: true, // show the mask-placeholder when hovering the empty input | ||
onKeyValidation: () => {}, // executes on every key-press with the result of isValid. Params: key, result, opts | ||
skipOptionalPartCharacter: " ", // a character which can be used to skip an optional part of a mask | ||
numericInput: false, // numericInput input direction style (input shifts to the left while holding the caret position) | ||
rightAlign: false, // align to the right | ||
undoOnEscape: true, // pressing escape reverts the value to the value before focus | ||
// numeric basic properties | ||
radixPoint: "", // ".", // | "," | ||
_radixDance: false, // dance around the radixPoint | ||
groupSeparator: "", // ",", // | "." | ||
// numeric basic properties | ||
keepStatic: null, // try to keep the mask static while typing. Decisions to alter the mask will be posponed if possible | ||
positionCaretOnTab: true, // when enabled the caret position is set after the latest valid position on TAB | ||
tabThrough: false, // allows for tabbing through the different parts of the masked field | ||
supportsInputType: ["text", "tel", "url", "password", "search"], // list with the supported input types | ||
isComplete: null, // override for isComplete - args => buffer, opts - return true || false | ||
preValidation: null, // hook to preValidate the input. Usefull for validating regardless the definition. args => buffer, pos, char, isSelection, opts, maskset, caretPos, strict => return true/false/command object | ||
postValidation: null, // hook to postValidate the result from isValid. Usefull for validating the entry as a whole. args => buffer, pos, c, currentResult, opts, maskset, strict, fromCheckval => return true/false/json | ||
staticDefinitionSymbol: undefined, // specify a definitionSymbol for static content, used to make matches for alternators | ||
jitMasking: false, // just in time masking ~ only mask while typing, can n (number), true or false | ||
nullable: true, // return nothing instead of the buffertemplate when the user hasn't entered anything. | ||
inputEventOnly: false, // dev option - testing inputfallback behavior | ||
noValuePatching: false, // disable value property patching | ||
positionCaretOnClick: "lvp", // none, lvp (based on the last valid position (default), radixFocus (position caret to radixpoint on initial click), select (select the whole input), ignore (ignore the click and continue the mask) | ||
casing: null, // mask-level casing. Options: null, "upper", "lower" or "title" or callback args => elem, test, pos, validPositions return charValue | ||
inputmode: "text", // specify the inputmode | ||
importDataAttributes: true, // import data-inputmask attributes | ||
shiftPositions: true, // shift position of the mask entries on entry and deletion. | ||
usePrototypeDefinitions: true, // use the default defined definitions from the prototype | ||
validationEventTimeOut: 3000, // Time to show validation error on form submit | ||
substitutes: {} // define character substitutes | ||
}; |
export default { | ||
"9": { //\uFF11-\uFF19 #1606 | ||
validator: "[0-9\uFF10-\uFF19]", | ||
definitionSymbol: "*" | ||
}, | ||
"a": { //\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5 #76 | ||
validator: "[A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]", | ||
definitionSymbol: "*" | ||
}, | ||
"*": { | ||
validator: "[0-9\uFF10-\uFF19A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]" | ||
} | ||
}; | ||
9: { | ||
// \uFF11-\uFF19 #1606 | ||
validator: "[0-9\uFF10-\uFF19]", | ||
definitionSymbol: "*" | ||
}, | ||
a: { | ||
// \u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5 #76 | ||
validator: "[A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]", | ||
definitionSymbol: "*" | ||
}, | ||
"*": { | ||
validator: | ||
"[0-9\uFF10-\uFF19A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]" | ||
} | ||
}; |
export default function (owner, key, value) { | ||
if (value === undefined) { | ||
return owner.__data ? owner.__data[key] : null; | ||
} else { | ||
owner.__data = owner.__data || {}; | ||
owner.__data[key] = value; | ||
} | ||
} | ||
if (value === undefined) { | ||
return owner.__data ? owner.__data[key] : null; | ||
} else { | ||
owner.__data = owner.__data || {}; | ||
owner.__data[key] = value; | ||
} | ||
} |
@@ -0,6 +1,7 @@ | ||
import window from "../global/window"; | ||
import extend from "./extend"; | ||
import window from "../global/window"; | ||
import DependencyLib from "./inputmask.dependencyLib"; | ||
export {on, off, trigger, Evnt as Event}; | ||
export { on, off, trigger, Evnt as Event }; | ||
@@ -10,3 +11,3 @@ const document = window.document; | ||
function isValidElement(elem) { | ||
return elem instanceof Element; | ||
return elem instanceof Element; | ||
} | ||
@@ -16,173 +17,216 @@ | ||
if (typeof window.CustomEvent === "function") { | ||
Evnt = window.CustomEvent; | ||
Evnt = window.CustomEvent; | ||
} else if (window.Event && document && document.createEvent) { | ||
Evnt = function (event, params) { | ||
params = params || {bubbles: false, cancelable: false, composed: true, detail: undefined}; | ||
var evt = document.createEvent("CustomEvent"); | ||
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); | ||
return evt; | ||
Evnt = function (event, params) { | ||
params = params || { | ||
bubbles: false, | ||
cancelable: false, | ||
composed: true, | ||
detail: undefined | ||
}; | ||
Evnt.prototype = window.Event.prototype; | ||
} else if (typeof Event != "undefined") { //nodejs | ||
Evnt = Event; | ||
const evt = document.createEvent("CustomEvent"); | ||
evt.initCustomEvent( | ||
event, | ||
params.bubbles, | ||
params.cancelable, | ||
params.detail | ||
); | ||
return evt; | ||
}; | ||
Evnt.prototype = window.Event.prototype; | ||
} else if (typeof Event !== "undefined") { | ||
// nodejs | ||
Evnt = Event; | ||
} | ||
function on(events, handler) { | ||
function addEvent(ev, namespace) { | ||
//register domevent | ||
if (elem.addEventListener) { // all browsers except IE before version 9 | ||
elem.addEventListener(ev, handler, false); | ||
} else if (elem.attachEvent) { // IE before version 9 | ||
elem.attachEvent(`on${ev}`, handler); | ||
} | ||
eventRegistry[ev] = eventRegistry[ev] || {}; | ||
eventRegistry[ev][namespace] = eventRegistry[ev][namespace] || []; | ||
eventRegistry[ev][namespace].push(handler); | ||
function addEvent(ev, namespace) { | ||
// register domevent | ||
if (elem.addEventListener) { | ||
// all browsers except IE before version 9 | ||
elem.addEventListener(ev, handler, false); | ||
} else if (elem.attachEvent) { | ||
// IE before version 9 | ||
elem.attachEvent(`on${ev}`, handler); | ||
} | ||
eventRegistry[ev] = eventRegistry[ev] || {}; | ||
eventRegistry[ev][namespace] = eventRegistry[ev][namespace] || []; | ||
eventRegistry[ev][namespace].push(handler); | ||
} | ||
if (isValidElement(this[0])) { | ||
var eventRegistry = this[0].eventRegistry, | ||
elem = this[0]; | ||
if (isValidElement(this[0])) { | ||
var eventRegistry = this[0].eventRegistry, | ||
elem = this[0]; | ||
events.split(" ").forEach((event) => { | ||
const [ev, namespace = "global"] = event.split("."); | ||
addEvent(ev, namespace); | ||
}); | ||
} | ||
return this; | ||
events.split(" ").forEach((event) => { | ||
const [ev, namespace = "global"] = event.split("."); | ||
addEvent(ev, namespace); | ||
}); | ||
} | ||
return this; | ||
} | ||
function off(events, handler) { | ||
var eventRegistry, elem; | ||
let eventRegistry, elem; | ||
function removeEvent(ev, namespace, handler) { | ||
if (ev in eventRegistry === true) { | ||
//unbind to dom events | ||
if (elem.removeEventListener) { // all browsers except IE before version 9 | ||
elem.removeEventListener(ev, handler, false); | ||
} else if (elem.detachEvent) { // IE before version 9 | ||
elem.detachEvent(`on${ev}`, handler); | ||
} | ||
if (namespace === "global") { | ||
for (var nmsp in eventRegistry[ev]) { | ||
eventRegistry[ev][nmsp].splice(eventRegistry[ev][nmsp].indexOf(handler), 1); | ||
} | ||
} else { | ||
eventRegistry[ev][namespace].splice(eventRegistry[ev][namespace].indexOf(handler), 1); | ||
} | ||
function removeEvent(ev, namespace, handler) { | ||
if (ev in eventRegistry === true) { | ||
// unbind to dom events | ||
if (elem.removeEventListener) { | ||
// all browsers except IE before version 9 | ||
elem.removeEventListener(ev, handler, false); | ||
} else if (elem.detachEvent) { | ||
// IE before version 9 | ||
elem.detachEvent(`on${ev}`, handler); | ||
} | ||
if (namespace === "global") { | ||
for (const nmsp in eventRegistry[ev]) { | ||
eventRegistry[ev][nmsp].splice( | ||
eventRegistry[ev][nmsp].indexOf(handler), | ||
1 | ||
); | ||
} | ||
} else { | ||
eventRegistry[ev][namespace].splice( | ||
eventRegistry[ev][namespace].indexOf(handler), | ||
1 | ||
); | ||
} | ||
} | ||
} | ||
function resolveNamespace(ev, namespace) { | ||
var evts = [], | ||
hndx, hndL; | ||
if (ev.length > 0) { | ||
function resolveNamespace(ev, namespace) { | ||
let evts = [], | ||
hndx, | ||
hndL; | ||
if (ev.length > 0) { | ||
if (handler === undefined) { | ||
for ( | ||
hndx = 0, hndL = eventRegistry[ev][namespace].length; | ||
hndx < hndL; | ||
hndx++ | ||
) { | ||
evts.push({ | ||
ev, | ||
namespace: namespace && namespace.length > 0 ? namespace : "global", | ||
handler: eventRegistry[ev][namespace][hndx] | ||
}); | ||
} | ||
} else { | ||
evts.push({ | ||
ev, | ||
namespace: namespace && namespace.length > 0 ? namespace : "global", | ||
handler | ||
}); | ||
} | ||
} else if (namespace.length > 0) { | ||
for (const evNdx in eventRegistry) { | ||
for (const nmsp in eventRegistry[evNdx]) { | ||
if (nmsp === namespace) { | ||
if (handler === undefined) { | ||
for (hndx = 0, hndL = eventRegistry[ev][namespace].length; hndx < hndL; hndx++) { | ||
evts.push({ | ||
ev: ev, | ||
namespace: namespace && namespace.length > 0 ? namespace : "global", | ||
handler: eventRegistry[ev][namespace][hndx] | ||
}); | ||
} | ||
} else { | ||
for ( | ||
hndx = 0, hndL = eventRegistry[evNdx][nmsp].length; | ||
hndx < hndL; | ||
hndx++ | ||
) { | ||
evts.push({ | ||
ev: ev, | ||
namespace: namespace && namespace.length > 0 ? namespace : "global", | ||
handler: handler | ||
ev: evNdx, | ||
namespace: nmsp, | ||
handler: eventRegistry[evNdx][nmsp][hndx] | ||
}); | ||
} | ||
} else { | ||
evts.push({ | ||
ev: evNdx, | ||
namespace: nmsp, | ||
handler | ||
}); | ||
} | ||
} else if (namespace.length > 0) { | ||
for (var evNdx in eventRegistry) { | ||
for (var nmsp in eventRegistry[evNdx]) { | ||
if (nmsp === namespace) { | ||
if (handler === undefined) { | ||
for (hndx = 0, hndL = eventRegistry[evNdx][nmsp].length; hndx < hndL; hndx++) { | ||
evts.push({ | ||
ev: evNdx, | ||
namespace: nmsp, | ||
handler: eventRegistry[evNdx][nmsp][hndx] | ||
}); | ||
} | ||
} else { | ||
evts.push({ | ||
ev: evNdx, | ||
namespace: nmsp, | ||
handler: handler | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return evts; | ||
} | ||
} | ||
if (isValidElement(this[0]) && events) { | ||
eventRegistry = this[0].eventRegistry; | ||
elem = this[0]; | ||
return evts; | ||
} | ||
events.split(" ").forEach((event) => { | ||
const [ev, namespace] = event.split("."); | ||
resolveNamespace(ev, namespace).forEach(({ev: ev1, handler: handler1, namespace: namespace1}) => { | ||
removeEvent(ev1, namespace1, handler1); | ||
}); | ||
}); | ||
} | ||
return this; | ||
if (isValidElement(this[0]) && events) { | ||
eventRegistry = this[0].eventRegistry; | ||
elem = this[0]; | ||
events.split(" ").forEach((event) => { | ||
const [ev, namespace] = event.split("."); | ||
resolveNamespace(ev, namespace).forEach( | ||
({ ev: ev1, handler: handler1, namespace: namespace1 }) => { | ||
removeEvent(ev1, namespace1, handler1); | ||
} | ||
); | ||
}); | ||
} | ||
return this; | ||
} | ||
function trigger(events /* , args... */) { | ||
if (isValidElement(this[0])) { | ||
var eventRegistry = this[0].eventRegistry, | ||
elem = this[0]; | ||
var _events = typeof events === "string" ? events.split(" ") : [events.type]; | ||
for (var endx = 0; endx < _events.length; endx++) { | ||
var nsEvent = _events[endx].split("."), | ||
ev = nsEvent[0], | ||
namespace = nsEvent[1] || "global"; | ||
if (document !== undefined && namespace === "global") { | ||
//trigger domevent | ||
var evnt, i, params = { | ||
bubbles: true, | ||
cancelable: true, | ||
composed: true, | ||
detail: arguments[1] | ||
}; | ||
// The custom event that will be created | ||
if (document.createEvent) { | ||
try { | ||
switch (ev) { | ||
case "input": | ||
params.inputType = "insertText"; | ||
evnt = new InputEvent(ev, params); | ||
break; | ||
default: | ||
evnt = new CustomEvent(ev, params); | ||
} | ||
} catch (e) { | ||
evnt = document.createEvent("CustomEvent"); | ||
evnt.initCustomEvent(ev, params.bubbles, params.cancelable, params.detail); | ||
} | ||
if (events.type) extend(evnt, events); | ||
elem.dispatchEvent(evnt); | ||
} else { | ||
evnt = document.createEventObject(); | ||
evnt.eventType = ev; | ||
evnt.detail = arguments[1]; | ||
if (events.type) extend(evnt, events); | ||
elem.fireEvent("on" + evnt.eventType, evnt); | ||
} | ||
} else if (eventRegistry[ev] !== undefined) { | ||
arguments[0] = arguments[0].type ? arguments[0] : DependencyLib.Event(arguments[0]); | ||
arguments[0].detail = arguments.slice(1); | ||
const registry = eventRegistry[ev], | ||
handlers = namespace === "global" ? Object.values(registry).flat() : registry[namespace]; | ||
handlers.forEach(handler => handler.apply(elem, arguments)); | ||
if (isValidElement(this[0])) { | ||
const eventRegistry = this[0].eventRegistry, | ||
elem = this[0], | ||
_events = typeof events === "string" ? events.split(" ") : [events.type]; | ||
for (let endx = 0; endx < _events.length; endx++) { | ||
const nsEvent = _events[endx].split("."), | ||
ev = nsEvent[0], | ||
namespace = nsEvent[1] || "global"; | ||
if (document !== undefined && namespace === "global") { | ||
// trigger domevent | ||
var evnt, | ||
params = { | ||
bubbles: true, | ||
cancelable: true, | ||
composed: true, | ||
detail: arguments[1] | ||
}; | ||
// The custom event that will be created | ||
if (document.createEvent) { | ||
try { | ||
switch (ev) { | ||
case "input": | ||
params.inputType = "insertText"; | ||
evnt = new InputEvent(ev, params); | ||
break; | ||
default: | ||
evnt = new CustomEvent(ev, params); | ||
} | ||
} catch (e) { | ||
evnt = document.createEvent("CustomEvent"); | ||
evnt.initCustomEvent( | ||
ev, | ||
params.bubbles, | ||
params.cancelable, | ||
params.detail | ||
); | ||
} | ||
if (events.type) extend(evnt, events); | ||
elem.dispatchEvent(evnt); | ||
} else { | ||
evnt = document.createEventObject(); | ||
evnt.eventType = ev; | ||
evnt.detail = arguments[1]; | ||
if (events.type) extend(evnt, events); | ||
elem.fireEvent("on" + evnt.eventType, evnt); | ||
} | ||
} else if (eventRegistry[ev] !== undefined) { | ||
arguments[0] = arguments[0].type | ||
? arguments[0] | ||
: DependencyLib.Event(arguments[0]); | ||
arguments[0].detail = arguments.slice(1); | ||
const registry = eventRegistry[ev], | ||
handlers = | ||
namespace === "global" | ||
? Object.values(registry).flat() | ||
: registry[namespace]; | ||
handlers.forEach((handler) => handler.apply(elem, arguments)); | ||
} | ||
} | ||
return this; | ||
} | ||
return this; | ||
} |
export default function extend() { | ||
let options, name, src, copy, copyIsArray, clone, | ||
target = arguments[0] || {}, | ||
i = 1, | ||
length = arguments.length, | ||
deep = false; | ||
let options, | ||
name, | ||
src, | ||
copy, | ||
copyIsArray, | ||
clone, | ||
target = arguments[0] || {}, | ||
i = 1, | ||
length = arguments.length, | ||
deep = false; | ||
// Handle a deep copy situation | ||
if (typeof target === "boolean") { | ||
deep = target; | ||
// Handle a deep copy situation | ||
if (typeof target === "boolean") { | ||
deep = target; | ||
// Skip the boolean and the target | ||
target = arguments[i] || {}; | ||
i++; | ||
} | ||
// Skip the boolean and the target | ||
target = arguments[i] || {}; | ||
i++; | ||
} | ||
// Handle case when target is a string or something (possible in deep copy) | ||
if (typeof target !== "object" && typeof target !== "function") { | ||
target = {}; | ||
} | ||
// Handle case when target is a string or something (possible in deep copy) | ||
if (typeof target !== "object" && typeof target !== "function") { | ||
target = {}; | ||
} | ||
for (; i < length; i++) { | ||
// Only deal with non-null/undefined values | ||
if ((options = arguments[i]) != null) { | ||
// Extend the base object | ||
for (name in options) { | ||
src = target[name]; | ||
copy = options[name]; | ||
for (; i < length; i++) { | ||
// Only deal with non-null/undefined values | ||
if ((options = arguments[i]) != null) { | ||
// Extend the base object | ||
for (name in options) { | ||
src = target[name]; | ||
copy = options[name]; | ||
// Prevent never-ending loop | ||
if (target === copy) { | ||
continue; | ||
} | ||
// Prevent never-ending loop | ||
if (target === copy) { | ||
continue; | ||
} | ||
// Recurse if we're merging plain objects or arrays | ||
if (deep && copy && (Object.prototype.toString.call(copy) === "[object Object]" || (copyIsArray = Array.isArray(copy)))) { | ||
if (copyIsArray) { | ||
copyIsArray = false; | ||
clone = src && Array.isArray(src) ? src : []; | ||
// Recurse if we're merging plain objects or arrays | ||
if ( | ||
deep && | ||
copy && | ||
(Object.prototype.toString.call(copy) === "[object Object]" || | ||
(copyIsArray = Array.isArray(copy))) | ||
) { | ||
if (copyIsArray) { | ||
copyIsArray = false; | ||
clone = src && Array.isArray(src) ? src : []; | ||
} else { | ||
clone = | ||
src && Object.prototype.toString.call(src) === "[object Object]" | ||
? src | ||
: {}; | ||
} | ||
} else { | ||
clone = src && Object.prototype.toString.call(src) === "[object Object]" ? src : {}; | ||
} | ||
// Never move original objects, clone them | ||
target[name] = extend(deep, clone, copy); | ||
// Never move original objects, clone them | ||
target[name] = extend(deep, clone, copy); | ||
// Don't bring in undefined values | ||
} else if (copy !== undefined) { | ||
target[name] = copy; | ||
} | ||
} | ||
} | ||
} | ||
// Don't bring in undefined values | ||
} else if (copy !== undefined) { | ||
target[name] = copy; | ||
} | ||
} | ||
} | ||
} | ||
// Return the modified object | ||
return target; | ||
} | ||
// Return the modified object | ||
return target; | ||
} |
@@ -11,4 +11,4 @@ /* | ||
if (jQuery === undefined) { | ||
throw "jQuery not loaded!"; | ||
throw new Error("jQuery not loaded!"); | ||
} | ||
export default jQuery; | ||
export default jQuery; |
@@ -8,6 +8,7 @@ /* | ||
import extend from "./extend"; | ||
import window from "../global/window"; | ||
import data from "./data"; | ||
import { on, off, trigger, Event} from "./events"; | ||
import { on, off, trigger, Event } from "./events"; | ||
import extend from "./extend"; | ||
@@ -17,23 +18,27 @@ const document = window.document; | ||
function DependencyLib(elem) { | ||
if (elem instanceof DependencyLib) { | ||
return elem; | ||
} | ||
if (!(this instanceof DependencyLib)) { | ||
return new DependencyLib(elem); | ||
} | ||
if (elem !== undefined && elem !== null && elem !== window) { | ||
this[0] = elem.nodeName ? elem : (elem[0] !== undefined && elem[0].nodeName ? elem[0] : document.querySelector(elem)); | ||
if (this[0] !== undefined && this[0] !== null) { | ||
this[0].eventRegistry = this[0].eventRegistry || {}; | ||
} | ||
} | ||
if (elem instanceof DependencyLib) { | ||
return elem; | ||
} | ||
if (!(this instanceof DependencyLib)) { | ||
return new DependencyLib(elem); | ||
} | ||
if (elem !== undefined && elem !== null && elem !== window) { | ||
this[0] = elem.nodeName | ||
? elem | ||
: elem[0] !== undefined && elem[0].nodeName | ||
? elem[0] | ||
: document.querySelector(elem); | ||
if (this[0] !== undefined && this[0] !== null) { | ||
this[0].eventRegistry = this[0].eventRegistry || {}; | ||
} | ||
} | ||
} | ||
DependencyLib.prototype = { | ||
on: on, | ||
off: off, | ||
trigger: trigger | ||
on, | ||
off, | ||
trigger | ||
}; | ||
//static | ||
// static | ||
DependencyLib.extend = extend; | ||
@@ -40,0 +45,0 @@ DependencyLib.data = data; |
import window from "./global/window"; | ||
const ua = (window.navigator && window.navigator.userAgent) || "", | ||
ie = (ua.indexOf("MSIE ") > 0) || (ua.indexOf("Trident/") > 0), | ||
mobile = (window.navigator && window.navigator.userAgentData && window.navigator.userAgentData.mobile) || (window.navigator && window.navigator.maxTouchPoints) || "ontouchstart" in window, //not entirely correct but will currently do | ||
iphone = /iphone/i.test(ua); | ||
ie = ua.indexOf("MSIE ") > 0 || ua.indexOf("Trident/") > 0, | ||
mobile = | ||
(window.navigator && | ||
window.navigator.userAgentData && | ||
window.navigator.userAgentData.mobile) || | ||
(window.navigator && window.navigator.maxTouchPoints) || | ||
"ontouchstart" in window, // not entirely correct but will currently do | ||
iphone = /iphone/i.test(ua); | ||
export {ie, mobile, iphone}; | ||
export { ie, mobile, iphone }; |
@@ -1,4 +0,25 @@ | ||
const escapeRegexRegex = new RegExp("(\\" + ["/", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}", "\\", "$", "^"].join("|\\") + ")", "gim"); | ||
const escapeRegexRegex = new RegExp( | ||
"(\\" + | ||
[ | ||
"/", | ||
".", | ||
"*", | ||
"+", | ||
"?", | ||
"|", | ||
"(", | ||
")", | ||
"[", | ||
"]", | ||
"{", | ||
"}", | ||
"\\", | ||
"$", | ||
"^" | ||
].join("|\\") + | ||
")", | ||
"gim" | ||
); | ||
export default function (str) { | ||
return str.replace(escapeRegexRegex, "\\$1"); | ||
} | ||
return str.replace(escapeRegexRegex, "\\$1"); | ||
} |
@@ -0,506 +1,749 @@ | ||
import { iphone, mobile } from "./environment"; | ||
import window from "./global/window"; | ||
import { | ||
caret, determineNewCaretPosition, | ||
getBuffer, getBufferTemplate, | ||
getLastValidPosition, isMask, | ||
resetMaskSet, | ||
seekNext, | ||
seekPrevious, | ||
translatePosition | ||
applyInputValue, | ||
checkVal, | ||
clearOptionalTail, | ||
HandleNativePlaceholder, | ||
writeBuffer | ||
} from "./inputHandling"; | ||
import { keys } from "./keycode.js"; | ||
import { | ||
caret, | ||
determineNewCaretPosition, | ||
getBuffer, | ||
getBufferTemplate, | ||
getLastValidPosition, | ||
isMask, | ||
resetMaskSet, | ||
seekNext, | ||
seekPrevious, | ||
translatePosition | ||
} from "./positioning"; | ||
import {keys} from "./keycode.js"; | ||
import {iphone, mobile} from "./environment"; | ||
import {handleRemove, isComplete, isSelection, isValid} from "./validation"; | ||
import {applyInputValue, checkVal, clearOptionalTail, HandleNativePlaceholder, writeBuffer} from "./inputHandling"; | ||
import {getPlaceholder, getTest} from "./validation-tests"; | ||
import window from "./global/window"; | ||
import { handleRemove, isComplete, isSelection, isValid } from "./validation"; | ||
import { getPlaceholder, getTest } from "./validation-tests"; | ||
export {EventHandlers}; | ||
export { EventHandlers }; | ||
var EventHandlers = { | ||
keyEvent: function (e, checkval, writeOut, strict, ndx) { | ||
const inputmask = this.inputmask, opts = inputmask.opts, $ = inputmask.dependencyLib, | ||
maskset = inputmask.maskset; | ||
keyEvent: function (e, checkval, writeOut, strict, ndx) { | ||
const inputmask = this.inputmask, | ||
opts = inputmask.opts, | ||
$ = inputmask.dependencyLib, | ||
maskset = inputmask.maskset, | ||
input = this, | ||
$input = $(input), | ||
c = e.key, | ||
pos = caret.call(inputmask, input), | ||
kdResult = opts.onKeyDown.call( | ||
this, | ||
e, | ||
getBuffer.call(inputmask), | ||
pos, | ||
opts | ||
); | ||
if (kdResult !== undefined) return kdResult; | ||
var input = this, | ||
$input = $(input), | ||
c = e.key, | ||
pos = caret.call(inputmask, input); | ||
// backspace, delete, and escape get special treatment | ||
if ( | ||
c === keys.Backspace || | ||
c === keys.Delete || | ||
(iphone && c === keys.BACKSPACE_SAFARI) || | ||
(e.ctrlKey && c === keys.x && !("oncut" in input)) | ||
) { | ||
// backspace/delete | ||
e.preventDefault(); // stop default action but allow propagation | ||
handleRemove.call(inputmask, input, c, pos); | ||
writeBuffer( | ||
input, | ||
getBuffer.call(inputmask, true), | ||
maskset.p, | ||
e, | ||
input.inputmask._valueGet() !== getBuffer.call(inputmask).join("") | ||
); | ||
} else if (c === keys.End || c === keys.PageDown) { | ||
// when END or PAGE_DOWN pressed set position at lastmatch | ||
e.preventDefault(); | ||
const caretPos = seekNext.call( | ||
inputmask, | ||
getLastValidPosition.call(inputmask) | ||
); | ||
caret.call( | ||
inputmask, | ||
input, | ||
e.shiftKey ? pos.begin : caretPos, | ||
caretPos, | ||
true | ||
); | ||
} else if ((c === keys.Home && !e.shiftKey) || c === keys.PageUp) { | ||
// Home or page_up | ||
e.preventDefault(); | ||
caret.call(inputmask, input, 0, e.shiftKey ? pos.begin : 0, true); | ||
} else if ( | ||
((opts.undoOnEscape && c === keys.Escape) || | ||
(false && c === keys.z && e.ctrlKey)) && | ||
e.altKey !== true | ||
) { | ||
// escape && undo && #762 | ||
checkVal(input, true, false, inputmask.undoValue.split("")); | ||
$input.trigger("click"); | ||
} else if ( | ||
c === keys.Insert && | ||
!(e.shiftKey || e.ctrlKey) && | ||
inputmask.userOptions.insertMode === undefined | ||
) { | ||
// insert | ||
if (!isSelection.call(inputmask, pos)) { | ||
opts.insertMode = !opts.insertMode; | ||
caret.call(inputmask, input, pos.begin, pos.begin); | ||
} else opts.insertMode = !opts.insertMode; | ||
} else if (opts.tabThrough === true && c === keys.Tab) { | ||
if (e.shiftKey === true) { | ||
pos.end = seekPrevious.call(inputmask, pos.end, true); | ||
if (getTest.call(inputmask, pos.end - 1).match.static === true) { | ||
pos.end--; | ||
} | ||
pos.begin = seekPrevious.call(inputmask, pos.end, true); | ||
if (pos.begin >= 0 && pos.end > 0) { | ||
e.preventDefault(); | ||
caret.call(inputmask, input, pos.begin, pos.end); | ||
} | ||
} else { | ||
pos.begin = seekNext.call(inputmask, pos.begin, true); | ||
pos.end = seekNext.call(inputmask, pos.begin, true); | ||
if (pos.end < maskset.maskLength) pos.end--; | ||
if (pos.begin <= maskset.maskLength) { | ||
e.preventDefault(); | ||
caret.call(inputmask, input, pos.begin, pos.end); | ||
} | ||
} | ||
} else if (!e.shiftKey) { | ||
if (opts.insertModeVisual && opts.insertMode === false) { | ||
if (c === keys.ArrowRight) { | ||
setTimeout(function () { | ||
const caretPos = caret.call(inputmask, input); | ||
caret.call(inputmask, input, caretPos.begin); | ||
}, 0); | ||
} else if (c === keys.ArrowLeft) { | ||
setTimeout(function () { | ||
const caretPos = { | ||
begin: translatePosition.call( | ||
inputmask, | ||
input.inputmask.caretPos.begin | ||
), | ||
end: translatePosition.call( | ||
inputmask, | ||
input.inputmask.caretPos.end | ||
) | ||
}; | ||
if (inputmask.isRTL) { | ||
caret.call( | ||
inputmask, | ||
input, | ||
caretPos.begin + (caretPos.begin === maskset.maskLength ? 0 : 1) | ||
); | ||
} else { | ||
caret.call( | ||
inputmask, | ||
input, | ||
caretPos.begin - (caretPos.begin === 0 ? 0 : 1) | ||
); | ||
} | ||
}, 0); | ||
} | ||
} else { | ||
inputmask.keyEventHook === undefined || inputmask.keyEventHook(e); | ||
} | ||
} | ||
var kdResult = opts.onKeyDown.call(this, e, getBuffer.call(inputmask), pos, opts); | ||
if (kdResult !== undefined) return kdResult; | ||
inputmask.isComposing = c == keys.Process || c == keys.Unidentified; | ||
inputmask.ignorable = | ||
c.length > 1 && | ||
!(input.tagName.toLowerCase() === "textarea" && c == keys.Enter); | ||
return EventHandlers.keypressEvent.call( | ||
this, | ||
e, | ||
checkval, | ||
writeOut, | ||
strict, | ||
ndx | ||
); | ||
}, | ||
keypressEvent: function (e, checkval, writeOut, strict, ndx) { | ||
const inputmask = this.inputmask || this, | ||
opts = inputmask.opts, | ||
$ = inputmask.dependencyLib, | ||
maskset = inputmask.maskset; | ||
//backspace, delete, and escape get special treatment | ||
if (c === keys.Backspace || c === keys.Delete || (iphone && c === keys.BACKSPACE_SAFARI) || (e.ctrlKey && c === keys.x && !("oncut" in input))) { //backspace/delete | ||
e.preventDefault(); //stop default action but allow propagation | ||
handleRemove.call(inputmask, input, c, pos); | ||
writeBuffer(input, getBuffer.call(inputmask, true), maskset.p, e, input.inputmask._valueGet() !== getBuffer.call(inputmask).join("")); | ||
} else if (c === keys.End || c === keys.PageDown) { //when END or PAGE_DOWN pressed set position at lastmatch | ||
e.preventDefault(); | ||
var caretPos = seekNext.call(inputmask, getLastValidPosition.call(inputmask)); | ||
caret.call(inputmask, input, e.shiftKey ? pos.begin : caretPos, caretPos, true); | ||
} else if ((c === keys.Home && !e.shiftKey) || c === keys.PageUp) { //Home or page_up | ||
e.preventDefault(); | ||
caret.call(inputmask, input, 0, e.shiftKey ? pos.begin : 0, true); | ||
} else if (((opts.undoOnEscape && c === keys.Escape) || (false && c === keys.z && e.ctrlKey)) && e.altKey !== true) { //escape && undo && #762 | ||
checkVal(input, true, false, inputmask.undoValue.split("")); | ||
$input.trigger("click"); | ||
} else if (c === keys.Insert && !(e.shiftKey || e.ctrlKey) && inputmask.userOptions.insertMode === undefined) { //insert | ||
if (!isSelection.call(inputmask, pos)) { | ||
opts.insertMode = !opts.insertMode; | ||
caret.call(inputmask, input, pos.begin, pos.begin); | ||
} else opts.insertMode = !opts.insertMode; | ||
} else if (opts.tabThrough === true && c === keys.Tab) { | ||
if (e.shiftKey === true) { | ||
pos.end = seekPrevious.call(inputmask, pos.end, true); | ||
if (getTest.call(inputmask, pos.end - 1).match.static === true) { | ||
pos.end--; | ||
} | ||
pos.begin = seekPrevious.call(inputmask, pos.end, true); | ||
if (pos.begin >= 0 && pos.end > 0) { | ||
e.preventDefault(); | ||
caret.call(inputmask, input, pos.begin, pos.end); | ||
} | ||
} else { | ||
pos.begin = seekNext.call(inputmask, pos.begin, true); | ||
pos.end = seekNext.call(inputmask, pos.begin, true); | ||
if (pos.end < maskset.maskLength) pos.end--; | ||
if (pos.begin <= maskset.maskLength) { | ||
e.preventDefault(); | ||
caret.call(inputmask, input, pos.begin, pos.end); | ||
} | ||
} | ||
} else if (!e.shiftKey) { | ||
if (opts.insertModeVisual && opts.insertMode === false) { | ||
if (c === keys.ArrowRight) { | ||
setTimeout(function () { | ||
var caretPos = caret.call(inputmask, input); | ||
caret.call(inputmask, input, caretPos.begin); | ||
}, 0); | ||
} else if (c === keys.ArrowLeft) { | ||
setTimeout(function () { | ||
var caretPos = { | ||
begin: translatePosition.call(inputmask, input.inputmask.caretPos.begin), | ||
end: translatePosition.call(inputmask, input.inputmask.caretPos.end) | ||
}; | ||
if (inputmask.isRTL) { | ||
caret.call(inputmask, input, caretPos.begin + (caretPos.begin === maskset.maskLength ? 0 : 1)); | ||
} else { | ||
caret.call(inputmask, input, caretPos.begin - (caretPos.begin === 0 ? 0 : 1)); | ||
} | ||
}, 0); | ||
} | ||
} else { | ||
inputmask.keyEventHook === undefined || inputmask.keyEventHook.call(inputmask, e); | ||
} | ||
} | ||
let input = inputmask.el, | ||
$input = $(input), | ||
c = e.key; | ||
inputmask.isComposing = (c == keys.Process || c == keys.Unidentified); | ||
inputmask.ignorable = c.length > 1 && !(input.tagName.toLowerCase() === "textarea" && k == keys.Enter); | ||
return EventHandlers.keypressEvent.call(this, e, checkval, writeOut, strict, ndx); | ||
}, | ||
keypressEvent: function (e, checkval, writeOut, strict, ndx) { | ||
const inputmask = this.inputmask || this, opts = inputmask.opts, $ = inputmask.dependencyLib, | ||
maskset = inputmask.maskset; | ||
if ( | ||
checkval !== true && | ||
!(e.ctrlKey && e.altKey && !inputmask.ignorable) && | ||
(e.ctrlKey || e.metaKey || inputmask.ignorable) | ||
) { | ||
if (c === keys.Enter) { | ||
if (inputmask.undoValue !== inputmask._valueGet(true)) { | ||
inputmask.undoValue = inputmask._valueGet(true); | ||
// e.preventDefault(); | ||
var input = inputmask.el, | ||
$input = $(input), | ||
c = e.key; | ||
setTimeout(function () { | ||
$input.trigger("change"); | ||
}, 0); | ||
} | ||
} | ||
// inputmask.skipInputEvent = true; //skip the input as otherwise the skipped char could be picked up for validation by the inputfallback | ||
} else if (c) { | ||
// special treat the decimal separator | ||
// if ((k === 44 || k === 46) && e.location === 3 && opts.radixPoint !== "") k = opts.radixPoint.charCodeAt(0); | ||
let pos = checkval | ||
? { | ||
begin: ndx, | ||
end: ndx | ||
} | ||
: caret.call(inputmask, input), | ||
forwardPosition; | ||
if (checkval !== true && (!(e.ctrlKey && e.altKey && !inputmask.ignorable) && (e.ctrlKey || e.metaKey || inputmask.ignorable))) { | ||
if (c === keys.Enter) { | ||
if (inputmask.undoValue !== inputmask._valueGet(true)) { | ||
inputmask.undoValue = inputmask._valueGet(true); | ||
// e.preventDefault(); | ||
// allow for character substitution | ||
if (!checkval) c = opts.substitutes[c] || c; | ||
maskset.writeOutBuffer = true; | ||
const valResult = isValid.call( | ||
inputmask, | ||
pos, | ||
c, | ||
strict, | ||
undefined, | ||
undefined, | ||
undefined, | ||
checkval | ||
); | ||
if (valResult !== false) { | ||
resetMaskSet.call(inputmask, true); | ||
forwardPosition = | ||
valResult.caret !== undefined | ||
? valResult.caret | ||
: seekNext.call( | ||
inputmask, | ||
valResult.pos.begin ? valResult.pos.begin : valResult.pos | ||
); | ||
maskset.p = forwardPosition; // needed for checkval | ||
} | ||
setTimeout(function () { | ||
$input.trigger("change"); | ||
}, 0); | ||
} | ||
} | ||
//inputmask.skipInputEvent = true; //skip the input as otherwise the skipped char could be picked up for validation by the inputfallback | ||
return; | ||
} else if (c) { | ||
//special treat the decimal separator | ||
// if ((k === 44 || k === 46) && e.location === 3 && opts.radixPoint !== "") k = opts.radixPoint.charCodeAt(0); | ||
var pos = checkval ? { | ||
begin: ndx, | ||
end: ndx | ||
} : caret.call(inputmask, input), | ||
forwardPosition; | ||
forwardPosition = | ||
opts.numericInput && valResult.caret === undefined | ||
? seekPrevious.call(inputmask, forwardPosition) | ||
: forwardPosition; | ||
if (writeOut !== false) { | ||
setTimeout(function () { | ||
opts.onKeyValidation.call(input, c, valResult); | ||
}, 0); | ||
if (maskset.writeOutBuffer && valResult !== false) { | ||
const buffer = getBuffer.call(inputmask); | ||
writeBuffer(input, buffer, forwardPosition, e, checkval !== true); | ||
} | ||
} | ||
//allow for character substitution | ||
if (!checkval) c = opts.substitutes[c] || c; | ||
maskset.writeOutBuffer = true; | ||
var valResult = isValid.call(inputmask, pos, c, strict, undefined, undefined, undefined, checkval); | ||
if (valResult !== false) { | ||
resetMaskSet.call(inputmask, true); | ||
forwardPosition = valResult.caret !== undefined ? valResult.caret : seekNext.call(inputmask, valResult.pos.begin ? valResult.pos.begin : valResult.pos); | ||
maskset.p = forwardPosition; //needed for checkval | ||
} | ||
e.preventDefault(); | ||
forwardPosition = ((opts.numericInput && valResult.caret === undefined) ? seekPrevious.call(inputmask, forwardPosition) : forwardPosition); | ||
if (writeOut !== false) { | ||
if (checkval) { | ||
if (valResult !== false) valResult.forwardPosition = forwardPosition; | ||
return valResult; | ||
} | ||
} | ||
}, | ||
pasteEvent: async function (e) { | ||
function handlePaste( | ||
inputmask, | ||
input, | ||
inputValue, | ||
pastedValue, | ||
onBeforePaste | ||
) { | ||
let caretPos = caret.call(inputmask, input, undefined, undefined, true), | ||
valueBeforeCaret = inputValue.substr(0, caretPos.begin), | ||
valueAfterCaret = inputValue.substr(caretPos.end, inputValue.length); | ||
setTimeout(function () { | ||
opts.onKeyValidation.call(input, c, valResult); | ||
}, 0); | ||
if (maskset.writeOutBuffer && valResult !== false) { | ||
var buffer = getBuffer.call(inputmask); | ||
writeBuffer(input, buffer, forwardPosition, e, checkval !== true); | ||
} | ||
} | ||
if ( | ||
valueBeforeCaret == | ||
(inputmask.isRTL | ||
? getBufferTemplate.call(inputmask).slice().reverse() | ||
: getBufferTemplate.call(inputmask) | ||
) | ||
.slice(0, caretPos.begin) | ||
.join("") | ||
) | ||
valueBeforeCaret = ""; | ||
if ( | ||
valueAfterCaret == | ||
(inputmask.isRTL | ||
? getBufferTemplate.call(inputmask).slice().reverse() | ||
: getBufferTemplate.call(inputmask) | ||
) | ||
.slice(caretPos.end) | ||
.join("") | ||
) | ||
valueAfterCaret = ""; | ||
e.preventDefault(); | ||
pastedValue = valueBeforeCaret + pastedValue + valueAfterCaret; | ||
if (inputmask.isRTL && opts.numericInput !== true) { | ||
pastedValue = pastedValue.split(""); | ||
for (const c of getBufferTemplate.call(inputmask)) { | ||
if (pastedValue[0] === c) pastedValue.shift(); | ||
} | ||
pastedValue = pastedValue.reverse().join(""); | ||
} | ||
if (checkval) { | ||
if (valResult !== false) valResult.forwardPosition = forwardPosition; | ||
return valResult; | ||
} | ||
} | ||
}, | ||
pasteEvent: async function (e) { | ||
function handlePaste(inputmask, input, inputValue, pastedValue, onBeforePaste) { | ||
var caretPos = caret.call(inputmask, input, undefined, undefined, true); | ||
let pasteValue = pastedValue; | ||
if (typeof onBeforePaste === "function") { | ||
pasteValue = onBeforePaste.call(inputmask, pasteValue, opts); | ||
if (pasteValue === false) { | ||
return false; | ||
} | ||
if (!pasteValue) { | ||
pasteValue = inputValue; | ||
} | ||
} | ||
checkVal(input, true, false, pasteValue.toString().split(""), e); | ||
} | ||
var valueBeforeCaret = inputValue.substr(0, caretPos.begin), | ||
valueAfterCaret = inputValue.substr(caretPos.end, inputValue.length); | ||
const input = this, | ||
inputmask = this.inputmask, | ||
opts = inputmask.opts; | ||
let inputValue = inputmask._valueGet(true), | ||
pastedValue; | ||
if (valueBeforeCaret == (inputmask.isRTL ? getBufferTemplate.call(inputmask).slice().reverse() : getBufferTemplate.call(inputmask)).slice(0, caretPos.begin).join("")) valueBeforeCaret = ""; | ||
if (valueAfterCaret == (inputmask.isRTL ? getBufferTemplate.call(inputmask).slice().reverse() : getBufferTemplate.call(inputmask)).slice(caretPos.end).join("")) valueAfterCaret = ""; | ||
inputmask.skipInputEvent = true; | ||
if (e.clipboardData && e.clipboardData.getData) { | ||
pastedValue = e.clipboardData.getData("text/plain"); | ||
} else if (window.clipboardData && window.clipboardData.getData) { | ||
// IE | ||
pastedValue = window.clipboardData.getData("Text"); | ||
} | ||
handlePaste(inputmask, input, inputValue, pastedValue, opts.onBeforePaste); | ||
e.preventDefault(); | ||
}, | ||
inputFallBackEvent: function (e) { | ||
// fallback when keypress is not triggered | ||
const inputmask = this.inputmask, | ||
opts = inputmask.opts, | ||
$ = inputmask.dependencyLib; | ||
pastedValue = valueBeforeCaret + pastedValue + valueAfterCaret; | ||
if (inputmask.isRTL && opts.numericInput !== true) { | ||
pastedValue = pastedValue.split(""); | ||
for (let c of getBufferTemplate.call(inputmask)) { | ||
if (pastedValue[0] === c) | ||
pastedValue.shift(); | ||
} | ||
pastedValue = pastedValue.reverse().join(""); | ||
} | ||
// console.log(e.inputType); | ||
var pasteValue = pastedValue; | ||
if (typeof onBeforePaste === "function") { | ||
pasteValue = onBeforePaste.call(inputmask, pasteValue, opts); | ||
if (pasteValue === false) { | ||
return false; | ||
} | ||
if (!pasteValue) { | ||
pasteValue = inputValue; | ||
} | ||
} | ||
checkVal(input, true, false, pasteValue.toString().split(""), e); | ||
} | ||
function analyseChanges(inputValue, buffer, caretPos) { | ||
let frontPart = inputValue.substr(0, caretPos.begin).split(""), | ||
backPart = inputValue.substr(caretPos.begin).split(""), | ||
frontBufferPart = buffer.substr(0, caretPos.begin).split(""), | ||
backBufferPart = buffer.substr(caretPos.begin).split(""), | ||
fpl = | ||
frontPart.length >= frontBufferPart.length | ||
? frontPart.length | ||
: frontBufferPart.length, | ||
bpl = | ||
backPart.length >= backBufferPart.length | ||
? backPart.length | ||
: backBufferPart.length, | ||
bl, | ||
i, | ||
action = "", | ||
data = [], | ||
marker = "~", | ||
placeholder; | ||
const input = this, inputmask = this.inputmask, opts = inputmask.opts; | ||
var inputValue = inputmask._valueGet(true), pastedValue; | ||
// align buffers | ||
while (frontPart.length < fpl) frontPart.push(marker); | ||
while (frontBufferPart.length < fpl) frontBufferPart.push(marker); | ||
while (backPart.length < bpl) backPart.unshift(marker); | ||
while (backBufferPart.length < bpl) backBufferPart.unshift(marker); | ||
inputmask.skipInputEvent = true; | ||
if (e.clipboardData && e.clipboardData.getData) { | ||
pastedValue = e.clipboardData.getData("text/plain"); | ||
} else if (window.clipboardData && window.clipboardData.getData) { // IE | ||
pastedValue = window.clipboardData.getData("Text"); | ||
} | ||
handlePaste(inputmask, input, inputValue, pastedValue, opts.onBeforePaste); | ||
e.preventDefault(); | ||
}, | ||
inputFallBackEvent: function (e) { //fallback when keypress is not triggered | ||
const inputmask = this.inputmask, opts = inputmask.opts, $ = inputmask.dependencyLib; | ||
const newBuffer = frontPart.concat(backPart), | ||
oldBuffer = frontBufferPart.concat(backBufferPart); | ||
// console.log(e.inputType); | ||
// console.log("N " + newBuffer); | ||
// console.log("O " + oldBuffer); | ||
function analyseChanges(inputValue, buffer, caretPos) { | ||
var frontPart = inputValue.substr(0, caretPos.begin).split(""), | ||
backPart = inputValue.substr(caretPos.begin).split(""), | ||
frontBufferPart = buffer.substr(0, caretPos.begin).split(""), | ||
backBufferPart = buffer.substr(caretPos.begin).split(""); | ||
for (i = 0, bl = newBuffer.length; i < bl; i++) { | ||
placeholder = getPlaceholder.call( | ||
inputmask, | ||
translatePosition.call(inputmask, i) | ||
); | ||
switch (action) { | ||
case "insertText": | ||
if ( | ||
oldBuffer[i - 1] === newBuffer[i] && | ||
caretPos.begin == newBuffer.length - 1 | ||
) { | ||
data.push(newBuffer[i]); | ||
} | ||
i = bl; | ||
break; | ||
case "insertReplacementText": | ||
if (newBuffer[i] === marker) { | ||
// extend selection | ||
caretPos.end++; | ||
} else { | ||
// breakout loop | ||
i = bl; | ||
} | ||
break; | ||
case "deleteContentBackward": | ||
if (newBuffer[i] === marker) { | ||
caretPos.end++; | ||
} else { | ||
// breakout loop | ||
i = bl; | ||
} | ||
break; | ||
default: | ||
if (newBuffer[i] !== oldBuffer[i]) { | ||
if ( | ||
(newBuffer[i + 1] === marker || | ||
newBuffer[i + 1] === placeholder || | ||
newBuffer[i + 1] === undefined) && | ||
((oldBuffer[i] === placeholder && | ||
oldBuffer[i + 1] === marker) || | ||
oldBuffer[i] === marker) | ||
) { | ||
// basic insert | ||
action = "insertText"; | ||
data.push(newBuffer[i]); | ||
caretPos.begin--; | ||
caretPos.end--; | ||
} else if ( | ||
oldBuffer[i + 1] === marker && | ||
oldBuffer[i] === newBuffer[i + 1] | ||
) { | ||
// insert between | ||
action = "insertText"; | ||
data.push(newBuffer[i]); | ||
caretPos.begin--; | ||
caretPos.end--; | ||
} else if ( | ||
newBuffer[i] !== placeholder && | ||
newBuffer[i] !== marker && | ||
(newBuffer[i + 1] === marker || | ||
(oldBuffer[i] !== newBuffer[i] && | ||
oldBuffer[i + 1] === | ||
newBuffer[i + 1])) /* single char replacement */ | ||
) { | ||
// replace selection | ||
action = "insertReplacementText"; | ||
data.push(newBuffer[i]); | ||
caretPos.begin--; | ||
} else if (newBuffer[i] === marker) { | ||
// delete~backspace | ||
action = "deleteContentBackward"; | ||
if ( | ||
isMask.call( | ||
inputmask, | ||
translatePosition.call(inputmask, i), | ||
true | ||
) || | ||
oldBuffer[i] === opts.radixPoint | ||
) | ||
caretPos.end++; | ||
} else { | ||
i = bl; | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
var fpl = frontPart.length >= frontBufferPart.length ? frontPart.length : frontBufferPart.length, | ||
bpl = backPart.length >= backBufferPart.length ? backPart.length : backBufferPart.length, | ||
bl, i, action = "", data = [], marker = "~", placeholder; | ||
return { | ||
action, | ||
data, | ||
caret: caretPos | ||
}; | ||
} | ||
//align buffers | ||
while (frontPart.length < fpl) frontPart.push(marker); | ||
while (frontBufferPart.length < fpl) frontBufferPart.push(marker); | ||
while (backPart.length < bpl) backPart.unshift(marker); | ||
while (backBufferPart.length < bpl) backBufferPart.unshift(marker); | ||
let input = this, | ||
inputValue = input.inputmask._valueGet(true), | ||
buffer = ( | ||
inputmask.isRTL | ||
? getBuffer.call(inputmask).slice().reverse() | ||
: getBuffer.call(inputmask) | ||
).join(""), | ||
caretPos = caret.call(inputmask, input, undefined, undefined, true), | ||
changes; | ||
var newBuffer = frontPart.concat(backPart); | ||
var oldBuffer = frontBufferPart.concat(backBufferPart); | ||
if (buffer !== inputValue) { | ||
changes = analyseChanges(inputValue, buffer, caretPos); | ||
if ( | ||
(input.inputmask.shadowRoot || input.ownerDocument).activeElement !== | ||
input | ||
) { | ||
input.focus(); | ||
} | ||
writeBuffer(input, getBuffer.call(inputmask)); | ||
caret.call(inputmask, input, caretPos.begin, caretPos.end, true); | ||
// console.log("N " + newBuffer); | ||
// console.log("O " + oldBuffer); | ||
// Japanese IME hack #2662 | ||
if ( | ||
!mobile && | ||
inputmask.skipNextInsert && | ||
e.inputType === "insertText" && | ||
changes.action === "insertText" && | ||
inputmask.isComposing | ||
) { | ||
return false; | ||
} | ||
if ( | ||
e.inputType === "insertCompositionText" && | ||
changes.action === "insertText" && | ||
inputmask.isComposing | ||
) { | ||
inputmask.skipNextInsert = true; | ||
} else { | ||
inputmask.skipNextInsert = false; | ||
} | ||
for (i = 0, bl = newBuffer.length; i < bl; i++) { | ||
placeholder = getPlaceholder.call(inputmask, translatePosition.call(inputmask, i)); | ||
switch (action) { | ||
case "insertText": | ||
if (oldBuffer[i - 1] === newBuffer[i] && caretPos.begin == newBuffer.length - 1) { | ||
data.push(newBuffer[i]); | ||
} | ||
i = bl; | ||
break; | ||
case "insertReplacementText": | ||
if (newBuffer[i] === marker) { //extend selection | ||
caretPos.end++; | ||
} else { | ||
// breakout loop | ||
i = bl; | ||
} | ||
break; | ||
case "deleteContentBackward": | ||
if (newBuffer[i] === marker) { | ||
caretPos.end++; | ||
} else { | ||
//breakout loop | ||
i = bl; | ||
} | ||
break; | ||
default: | ||
if (newBuffer[i] !== oldBuffer[i]) { | ||
if ((newBuffer[i + 1] === marker || newBuffer[i + 1] === placeholder || newBuffer[i + 1] === undefined) && ((oldBuffer[i] === placeholder && oldBuffer[i + 1] === marker) || oldBuffer[i] === marker)) { //basic insert | ||
action = "insertText"; | ||
data.push(newBuffer[i]); | ||
caretPos.begin--; | ||
caretPos.end--; | ||
} else if (oldBuffer[i + 1] === marker && oldBuffer[i] === newBuffer[i + 1]) { //insert between | ||
action = "insertText"; | ||
data.push(newBuffer[i]); | ||
caretPos.begin--; | ||
caretPos.end--; | ||
} else if (newBuffer[i] !== placeholder && newBuffer[i] !== marker && | ||
(newBuffer[i + 1] === marker || (oldBuffer[i] !== newBuffer[i] && oldBuffer[i + 1] === newBuffer[i + 1] /*single char replacement*/))) { //replace selection | ||
action = "insertReplacementText"; | ||
data.push(newBuffer[i]); | ||
caretPos.begin--; | ||
} else if (newBuffer[i] === marker) { //delete~backspace | ||
action = "deleteContentBackward"; | ||
if (isMask.call(inputmask, translatePosition.call(inputmask, i), true) || oldBuffer[i] === opts.radixPoint) caretPos.end++; | ||
} else { | ||
i = bl; | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
switch (changes.action) { | ||
case "insertText": | ||
case "insertReplacementText": | ||
changes.data.forEach(function (entry, ndx) { | ||
const keypress = new $.Event("keypress"); | ||
keypress.key = entry; | ||
inputmask.ignorable = false; // make sure ignorable is ignored ;-) | ||
EventHandlers.keypressEvent.call(input, keypress); | ||
}); | ||
setTimeout(function () { | ||
// #2195 trigger keyup to help some other plugins to track changes | ||
inputmask.$el.trigger("keyup"); | ||
}, 0); | ||
break; | ||
case "deleteContentBackward": | ||
var keydown = new $.Event("keydown"); | ||
keydown.key = keys.Backspace; | ||
EventHandlers.keyEvent.call(input, keydown); | ||
break; | ||
default: | ||
applyInputValue(input, inputValue); | ||
caret.call(inputmask, input, caretPos.begin, caretPos.end, true); | ||
break; | ||
} | ||
return { | ||
action: action, | ||
data: data, | ||
caret: caretPos | ||
}; | ||
} | ||
e.preventDefault(); | ||
} | ||
}, | ||
setValueEvent: function (e) { | ||
const inputmask = this.inputmask, | ||
$ = inputmask.dependencyLib; | ||
let input = this, | ||
value = e && e.detail ? e.detail[0] : arguments[1]; | ||
var input = this, | ||
inputValue = input.inputmask._valueGet(true), | ||
buffer = (inputmask.isRTL ? getBuffer.call(inputmask).slice().reverse() : getBuffer.call(inputmask)).join(""), | ||
caretPos = caret.call(inputmask, input, undefined, undefined, true), | ||
changes; | ||
if (value === undefined) { | ||
value = input.inputmask._valueGet(true); | ||
} | ||
if (buffer !== inputValue) { | ||
changes = analyseChanges(inputValue, buffer, caretPos); | ||
if ((input.inputmask.shadowRoot || input.ownerDocument).activeElement !== input) { | ||
input.focus(); | ||
} | ||
writeBuffer(input, getBuffer.call(inputmask)); | ||
caret.call(inputmask, input, caretPos.begin, caretPos.end, true); | ||
applyInputValue(input, value, new $.Event("input")); | ||
// Japanese IME hack #2662 | ||
if (!mobile && inputmask.skipNextInsert && e.inputType === "insertText" && changes.action === "insertText" && inputmask.isComposing) { | ||
return false; | ||
} | ||
if (e.inputType === "insertCompositionText" && changes.action === "insertText" && inputmask.isComposing) { | ||
inputmask.skipNextInsert = true; | ||
} else { | ||
inputmask.skipNextInsert = false; | ||
} | ||
if ((e.detail && e.detail[1] !== undefined) || arguments[2] !== undefined) { | ||
caret.call(inputmask, input, e.detail ? e.detail[1] : arguments[2]); | ||
} | ||
}, | ||
focusEvent: function (e) { | ||
const inputmask = this.inputmask, | ||
opts = inputmask.opts, | ||
input = this, | ||
nptValue = inputmask && inputmask._valueGet(); | ||
switch (changes.action) { | ||
case "insertText": | ||
case "insertReplacementText": | ||
changes.data.forEach(function (entry, ndx) { | ||
var keypress = new $.Event("keypress"); | ||
keypress.key = entry; | ||
inputmask.ignorable = false; //make sure ignorable is ignored ;-) | ||
EventHandlers.keypressEvent.call(input, keypress); | ||
}); | ||
setTimeout(function () { //#2195 trigger keyup to help some other plugins to track changes | ||
inputmask.$el.trigger("keyup"); | ||
}, 0); | ||
break; | ||
case "deleteContentBackward": | ||
var keydown = new $.Event("keydown"); | ||
keydown.key = keys.Backspace; | ||
EventHandlers.keyEvent.call(input, keydown); | ||
break; | ||
default: | ||
applyInputValue(input, inputValue); | ||
caret.call(inputmask, input, caretPos.begin, caretPos.end, true); | ||
break; | ||
} | ||
e.preventDefault(); | ||
} | ||
}, | ||
setValueEvent: function (e) { | ||
const inputmask = this.inputmask, $ = inputmask.dependencyLib; | ||
var input = this, | ||
value = (e && e.detail) ? e.detail[0] : arguments[1]; | ||
if (value === undefined) { | ||
value = input.inputmask._valueGet(true); | ||
} | ||
applyInputValue(input, value, new $.Event("input")); | ||
if ((e.detail && e.detail[1] !== undefined) || arguments[2] !== undefined) { | ||
caret.call(inputmask, input, e.detail ? e.detail[1] : arguments[2]); | ||
} | ||
} | ||
, | ||
focusEvent: function (e) { | ||
const inputmask = this.inputmask, opts = inputmask.opts; | ||
var input = this, | ||
nptValue = inputmask && inputmask._valueGet(); | ||
if (opts.showMaskOnFocus) { | ||
if (nptValue !== getBuffer.call(inputmask).join("")) { | ||
writeBuffer(input, getBuffer.call(inputmask), seekNext.call(inputmask, getLastValidPosition.call(inputmask))); | ||
} /*else if (mouseEnter === false) { //only executed on focus without mouseenter | ||
if (opts.showMaskOnFocus) { | ||
if (nptValue !== getBuffer.call(inputmask).join("")) { | ||
writeBuffer( | ||
input, | ||
getBuffer.call(inputmask), | ||
seekNext.call(inputmask, getLastValidPosition.call(inputmask)) | ||
); | ||
} /* else if (mouseEnter === false) { //only executed on focus without mouseenter | ||
caret(input, seekNext(getLastValidPosition())); | ||
}*/ | ||
} | ||
if (opts.positionCaretOnTab === true && inputmask.mouseEnter === false && (!isComplete.call(inputmask, getBuffer.call(inputmask)) || getLastValidPosition.call(inputmask) === -1)) { | ||
EventHandlers.clickEvent.apply(input, [e, true]); | ||
} | ||
inputmask.undoValue = inputmask && inputmask._valueGet(true); | ||
}, | ||
invalidEvent: function (e) { | ||
this.inputmask.validationEvent = true; | ||
}, | ||
mouseleaveEvent: function () { | ||
const inputmask = this.inputmask, opts = inputmask.opts; | ||
} */ | ||
} | ||
if ( | ||
opts.positionCaretOnTab === true && | ||
inputmask.mouseEnter === false && | ||
(!isComplete.call(inputmask, getBuffer.call(inputmask)) || | ||
getLastValidPosition.call(inputmask) === -1) | ||
) { | ||
EventHandlers.clickEvent.apply(input, [e, true]); | ||
} | ||
inputmask.undoValue = inputmask && inputmask._valueGet(true); | ||
}, | ||
invalidEvent: function (e) { | ||
this.inputmask.validationEvent = true; | ||
}, | ||
mouseleaveEvent: function () { | ||
const inputmask = this.inputmask, | ||
opts = inputmask.opts, | ||
input = this; | ||
inputmask.mouseEnter = false; | ||
if ( | ||
opts.clearMaskOnLostFocus && | ||
(input.inputmask.shadowRoot || input.ownerDocument).activeElement !== | ||
input | ||
) { | ||
HandleNativePlaceholder(input, inputmask.originalPlaceholder); | ||
} | ||
}, | ||
clickEvent: function (e, tabbed) { | ||
const inputmask = this.inputmask; | ||
inputmask.clicked++; | ||
var input = this; | ||
inputmask.mouseEnter = false; | ||
if (opts.clearMaskOnLostFocus && (input.inputmask.shadowRoot || input.ownerDocument).activeElement !== input) { | ||
HandleNativePlaceholder(input, inputmask.originalPlaceholder); | ||
} | ||
}, | ||
clickEvent: function (e, tabbed) { | ||
const inputmask = this.inputmask; | ||
inputmask.clicked++; | ||
const input = this; | ||
if ( | ||
(input.inputmask.shadowRoot || input.ownerDocument).activeElement === | ||
input | ||
) { | ||
const newCaretPosition = determineNewCaretPosition.call( | ||
inputmask, | ||
caret.call(inputmask, input), | ||
tabbed | ||
); | ||
if (newCaretPosition !== undefined) { | ||
caret.call(inputmask, input, newCaretPosition); | ||
} | ||
} | ||
}, | ||
cutEvent: function (e) { | ||
const inputmask = this.inputmask, | ||
maskset = inputmask.maskset, | ||
input = this, | ||
pos = caret.call(inputmask, input), | ||
// correct clipboardData | ||
clipData = inputmask.isRTL | ||
? getBuffer.call(inputmask).slice(pos.end, pos.begin) | ||
: getBuffer.call(inputmask).slice(pos.begin, pos.end), | ||
clipDataText = inputmask.isRTL | ||
? clipData.reverse().join("") | ||
: clipData.join(""); | ||
if (window.navigator && window.navigator.clipboard) | ||
window.navigator.clipboard.writeText(clipDataText); | ||
else if (window.clipboardData && window.clipboardData.getData) { | ||
// IE | ||
window.clipboardData.setData("Text", clipDataText); | ||
} | ||
handleRemove.call(inputmask, input, keys.Delete, pos); | ||
writeBuffer( | ||
input, | ||
getBuffer.call(inputmask), | ||
maskset.p, | ||
e, | ||
inputmask.undoValue !== inputmask._valueGet(true) | ||
); | ||
}, | ||
blurEvent: function (e) { | ||
const inputmask = this.inputmask, | ||
opts = inputmask.opts, | ||
$ = inputmask.dependencyLib; | ||
inputmask.clicked = 0; | ||
var input = this; | ||
if ((input.inputmask.shadowRoot || input.ownerDocument).activeElement === input) { | ||
var newCaretPosition = determineNewCaretPosition.call(inputmask, caret.call(inputmask, input), tabbed); | ||
if (newCaretPosition !== undefined) { | ||
caret.call(inputmask, input, newCaretPosition); | ||
} | ||
} | ||
}, | ||
cutEvent: function (e) { | ||
const inputmask = this.inputmask, maskset = inputmask.maskset; | ||
const $input = $(this), | ||
input = this; | ||
if (input.inputmask) { | ||
HandleNativePlaceholder(input, inputmask.originalPlaceholder); | ||
let nptValue = input.inputmask._valueGet(), | ||
buffer = getBuffer.call(inputmask).slice(); | ||
var input = this, | ||
pos = caret.call(inputmask, input); | ||
if (nptValue !== "") { | ||
if (opts.clearMaskOnLostFocus) { | ||
if ( | ||
getLastValidPosition.call(inputmask) === -1 && | ||
nptValue === getBufferTemplate.call(inputmask).join("") | ||
) { | ||
buffer = []; | ||
} else { | ||
// clearout optional tail of the mask | ||
clearOptionalTail.call(inputmask, buffer); | ||
} | ||
} | ||
if (isComplete.call(inputmask, buffer) === false) { | ||
setTimeout(function () { | ||
$input.trigger("incomplete"); | ||
}, 0); | ||
if (opts.clearIncomplete) { | ||
resetMaskSet.call(inputmask, false); | ||
if (opts.clearMaskOnLostFocus) { | ||
buffer = []; | ||
} else { | ||
buffer = getBufferTemplate.call(inputmask).slice(); | ||
} | ||
} | ||
} | ||
//correct clipboardData | ||
var clipData = inputmask.isRTL ? getBuffer.call(inputmask).slice(pos.end, pos.begin) : getBuffer.call(inputmask).slice(pos.begin, pos.end), | ||
clipDataText = inputmask.isRTL ? clipData.reverse().join("") : clipData.join(""); | ||
if (window.navigator && window.navigator.clipboard) | ||
window.navigator.clipboard.writeText(clipDataText); | ||
else if (window.clipboardData && window.clipboardData.getData) { // IE | ||
window.clipboardData.setData("Text", clipDataText); | ||
} | ||
handleRemove.call(inputmask, input, keys.Delete, pos); | ||
writeBuffer(input, getBuffer.call(inputmask), maskset.p, e, inputmask.undoValue !== inputmask._valueGet(true)); | ||
}, | ||
blurEvent: function (e) { | ||
const inputmask = this.inputmask, opts = inputmask.opts, $ = inputmask.dependencyLib; | ||
inputmask.clicked = 0; | ||
writeBuffer(input, buffer, undefined, e); | ||
} | ||
var $input = $(this), | ||
input = this; | ||
if (input.inputmask) { | ||
HandleNativePlaceholder(input, inputmask.originalPlaceholder); | ||
var nptValue = input.inputmask._valueGet(), | ||
buffer = getBuffer.call(inputmask).slice(); | ||
nptValue = inputmask._valueGet(true); | ||
if (inputmask.undoValue !== nptValue) { | ||
if ( | ||
nptValue != "" || | ||
inputmask.undoValue != getBufferTemplate.call(inputmask).join("") || | ||
(inputmask.undoValue == getBufferTemplate.call(inputmask).join("") && | ||
inputmask.maskset.validPositions.length > 0) | ||
) { | ||
inputmask.undoValue = nptValue; | ||
$input.trigger("change"); | ||
} | ||
} | ||
} | ||
}, | ||
mouseenterEvent: function () { | ||
const inputmask = this.inputmask, | ||
{ showMaskOnHover } = inputmask.opts, | ||
input = this; | ||
inputmask.mouseEnter = true; | ||
if ( | ||
(input.inputmask.shadowRoot || input.ownerDocument).activeElement !== | ||
input | ||
) { | ||
const bufferTemplate = ( | ||
inputmask.isRTL | ||
? getBufferTemplate.call(inputmask).slice().reverse() | ||
: getBufferTemplate.call(inputmask) | ||
).join(""); | ||
if (showMaskOnHover) { | ||
HandleNativePlaceholder(input, bufferTemplate); | ||
} | ||
} | ||
}, | ||
submitEvent: function () { | ||
// trigger change on submit if any | ||
const inputmask = this.inputmask, | ||
opts = inputmask.opts; | ||
if (nptValue !== "") { | ||
if (opts.clearMaskOnLostFocus) { | ||
if (getLastValidPosition.call(inputmask) === -1 && nptValue === getBufferTemplate.call(inputmask).join("")) { | ||
buffer = []; | ||
} else { //clearout optional tail of the mask | ||
clearOptionalTail.call(inputmask, buffer); | ||
} | ||
} | ||
if (isComplete.call(inputmask, buffer) === false) { | ||
setTimeout(function () { | ||
$input.trigger("incomplete"); | ||
}, 0); | ||
if (opts.clearIncomplete) { | ||
resetMaskSet.call(inputmask, false); | ||
if (opts.clearMaskOnLostFocus) { | ||
buffer = []; | ||
} else { | ||
buffer = getBufferTemplate.call(inputmask).slice(); | ||
} | ||
if (inputmask.undoValue !== inputmask._valueGet(true)) { | ||
inputmask.$el.trigger("change"); | ||
} | ||
if ( | ||
/* opts.clearMaskOnLostFocus && */ getLastValidPosition.call( | ||
inputmask | ||
) === -1 && | ||
inputmask._valueGet && | ||
inputmask._valueGet() === getBufferTemplate.call(inputmask).join("") | ||
) { | ||
inputmask._valueSet(""); // clear masktemplete on submit and still has focus | ||
} | ||
if ( | ||
opts.clearIncomplete && | ||
isComplete.call(inputmask, getBuffer.call(inputmask)) === false | ||
) { | ||
inputmask._valueSet(""); | ||
} | ||
if (opts.removeMaskOnSubmit) { | ||
inputmask._valueSet(inputmask.unmaskedvalue(), true); | ||
setTimeout(function () { | ||
writeBuffer(inputmask.el, getBuffer.call(inputmask)); | ||
}, 0); | ||
} | ||
}, | ||
resetEvent: function () { | ||
const inputmask = this.inputmask; | ||
} | ||
} | ||
writeBuffer(input, buffer, undefined, e); | ||
} | ||
nptValue = inputmask._valueGet(true); | ||
if (inputmask.undoValue !== nptValue) { | ||
if (nptValue != "" || (inputmask.undoValue != getBufferTemplate.call(inputmask).join("") || (inputmask.undoValue == getBufferTemplate.call(inputmask).join("") && inputmask.maskset.validPositions.length > 0))) { | ||
inputmask.undoValue = nptValue; | ||
$input.trigger("change"); | ||
} | ||
} | ||
} | ||
} | ||
, | ||
mouseenterEvent: function () { | ||
const inputmask = this.inputmask, {showMaskOnHover} = inputmask.opts; | ||
var input = this; | ||
inputmask.mouseEnter = true; | ||
if ((input.inputmask.shadowRoot || input.ownerDocument).activeElement !== input) { | ||
var bufferTemplate = (inputmask.isRTL ? getBufferTemplate.call(inputmask).slice().reverse() : getBufferTemplate.call(inputmask)).join(""); | ||
if (showMaskOnHover) { | ||
HandleNativePlaceholder(input, bufferTemplate); | ||
} | ||
} | ||
} | ||
, | ||
submitEvent: function () { //trigger change on submit if any | ||
const inputmask = this.inputmask, opts = inputmask.opts; | ||
if (inputmask.undoValue !== inputmask._valueGet(true)) { | ||
inputmask.$el.trigger("change"); | ||
} | ||
if (/*opts.clearMaskOnLostFocus && */getLastValidPosition.call(inputmask) === -1 && inputmask._valueGet && inputmask._valueGet() === getBufferTemplate.call(inputmask).join("")) { | ||
inputmask._valueSet(""); //clear masktemplete on submit and still has focus | ||
} | ||
if (opts.clearIncomplete && isComplete.call(inputmask, getBuffer.call(inputmask)) === false) { | ||
inputmask._valueSet(""); | ||
} | ||
if (opts.removeMaskOnSubmit) { | ||
inputmask._valueSet(inputmask.unmaskedvalue(), true); | ||
setTimeout(function () { | ||
writeBuffer(inputmask.el, getBuffer.call(inputmask)); | ||
}, 0); | ||
} | ||
} | ||
, | ||
resetEvent: function () { | ||
const inputmask = this.inputmask; | ||
inputmask.refreshValue = true; //indicate a forced refresh when there is a call to the value before leaving the triggering event fn | ||
setTimeout(function () { | ||
applyInputValue(inputmask.el, inputmask._valueGet(true)); | ||
}, 0); | ||
} | ||
inputmask.refreshValue = true; // indicate a forced refresh when there is a call to the value before leaving the triggering event fn | ||
setTimeout(function () { | ||
applyInputValue(inputmask.el, inputmask._valueGet(true)); | ||
}, 0); | ||
} | ||
}; |
@@ -0,107 +1,127 @@ | ||
import { HandleNativePlaceholder } from "./inputHandling"; | ||
import Inputmask from "./inputmask"; | ||
import {keys} from "./keycode.js"; | ||
import {getBufferTemplate} from "./positioning"; | ||
import {HandleNativePlaceholder} from "./inputHandling"; | ||
import { keys } from "./keycode.js"; | ||
import { getBufferTemplate } from "./positioning"; | ||
export {EventRuler}; | ||
export { EventRuler }; | ||
var EventRuler = { | ||
on: function (input, eventName, eventHandler) { | ||
const $ = input.inputmask.dependencyLib; | ||
on: function (input, eventName, eventHandler) { | ||
const $ = input.inputmask.dependencyLib; | ||
var ev = function (e) { | ||
if (e.originalEvent) { | ||
e = e.originalEvent || e; //get original event from jquery evenbt | ||
arguments[0] = e; | ||
let ev = function (e) { | ||
if (e.originalEvent) { | ||
e = e.originalEvent || e; // get original event from jquery evenbt | ||
arguments[0] = e; | ||
} | ||
// console.log(e.type); | ||
let that = this, | ||
args, | ||
inputmask = that.inputmask, | ||
opts = inputmask ? inputmask.opts : undefined; | ||
if (inputmask === undefined && this.nodeName !== "FORM") { | ||
// happens when cloning an object with jquery.clone | ||
const imOpts = $.data(that, "_inputmask_opts"); | ||
$(that).off(); // unbind all events | ||
if (imOpts) { | ||
new Inputmask(imOpts).mask(that); | ||
} | ||
} else if ( | ||
!["submit", "reset", "setvalue"].includes(e.type) && | ||
this.nodeName !== "FORM" && | ||
(that.disabled || | ||
(that.readOnly && | ||
!( | ||
(e.type === "keydown" && e.ctrlKey && e.key === keys.c) || | ||
(opts.tabThrough === false && e.key === keys.Tab) | ||
))) | ||
) { | ||
e.preventDefault(); | ||
} else { | ||
switch (e.type) { | ||
case "input": | ||
if (inputmask.skipInputEvent === true) { | ||
inputmask.skipInputEvent = false; | ||
return e.preventDefault(); | ||
} | ||
// console.log(e.type); | ||
var that = this, args, inputmask = that.inputmask, opts = inputmask ? inputmask.opts : undefined; | ||
if (inputmask === undefined && this.nodeName !== "FORM") { //happens when cloning an object with jquery.clone | ||
var imOpts = $.data(that, "_inputmask_opts"); | ||
$(that).off(); //unbind all events | ||
if (imOpts) { | ||
(new Inputmask(imOpts)).mask(that); | ||
} | ||
} else if (!["submit", "reset", "setvalue"].includes(e.type) && this.nodeName !== "FORM" && (that.disabled || (that.readOnly && !(e.type === "keydown" && (e.ctrlKey && e.key === keys.c) || (opts.tabThrough === false && e.key === keys.Tab))))) { | ||
e.preventDefault(); | ||
} else { | ||
switch (e.type) { | ||
case "input": | ||
if (inputmask.skipInputEvent === true) { | ||
inputmask.skipInputEvent = false; | ||
return e.preventDefault(); | ||
} | ||
// if (mobile) { //this causes problem see #2220 | ||
// args = arguments; | ||
// setTimeout(function () { //needed for caret selection when entering a char on Android 8 - #1818 | ||
// eventHandler.apply(that, args); | ||
// caret(that, that.inputmask.caretPos, undefined, true); | ||
// }, 0); | ||
// return false; | ||
// } | ||
break; | ||
case "click": | ||
case "focus": | ||
if (inputmask.validationEvent) { // #841 | ||
inputmask.validationEvent = false; | ||
input.blur(); | ||
HandleNativePlaceholder(input, (inputmask.isRTL ? getBufferTemplate.call(inputmask).slice().reverse() : getBufferTemplate.call(inputmask)).join("")); | ||
setTimeout(function () { | ||
input.focus(); | ||
}, opts.validationEventTimeOut); | ||
return false; | ||
} | ||
args = arguments; | ||
setTimeout(function () { //needed for Chrome ~ initial selection clears after the clickevent | ||
if (!input.inputmask) { | ||
// `inputmask.remove()` was called before this callback | ||
return; | ||
} | ||
eventHandler.apply(that, args); | ||
}, 0); | ||
return /*false*/; //#2423 | ||
} | ||
var returnVal = eventHandler.apply(that, arguments); | ||
if (returnVal === false) { | ||
e.preventDefault(); | ||
e.stopPropagation(); | ||
} | ||
return returnVal; | ||
// if (mobile) { //this causes problem see #2220 | ||
// args = arguments; | ||
// setTimeout(function () { //needed for caret selection when entering a char on Android 8 - #1818 | ||
// eventHandler.apply(that, args); | ||
// caret(that, that.inputmask.caretPos, undefined, true); | ||
// }, 0); | ||
// return false; | ||
// } | ||
break; | ||
case "click": | ||
case "focus": | ||
if (inputmask.validationEvent) { | ||
// #841 | ||
inputmask.validationEvent = false; | ||
input.blur(); | ||
HandleNativePlaceholder( | ||
input, | ||
(inputmask.isRTL | ||
? getBufferTemplate.call(inputmask).slice().reverse() | ||
: getBufferTemplate.call(inputmask) | ||
).join("") | ||
); | ||
setTimeout(function () { | ||
input.focus(); | ||
}, opts.validationEventTimeOut); | ||
return false; | ||
} | ||
}; | ||
if (["submit", "reset"].includes(eventName)) { | ||
ev = ev.bind(input); //bind creates a new eventhandler (wrap) | ||
if (input.form !== null) $(input.form).on(eventName, ev); | ||
} else { | ||
$(input).on(eventName, ev); | ||
args = arguments; | ||
setTimeout(function () { | ||
// needed for Chrome ~ initial selection clears after the clickevent | ||
if (!input.inputmask) { | ||
// `inputmask.remove()` was called before this callback | ||
return; | ||
} | ||
eventHandler.apply(that, args); | ||
}, 0); | ||
return /* false */; // #2423 | ||
} | ||
const returnVal = eventHandler.apply(that, arguments); | ||
if (returnVal === false) { | ||
e.preventDefault(); | ||
e.stopPropagation(); | ||
} | ||
return returnVal; | ||
} | ||
}; | ||
if (["submit", "reset"].includes(eventName)) { | ||
ev = ev.bind(input); // bind creates a new eventhandler (wrap) | ||
if (input.form !== null) $(input.form).on(eventName, ev); | ||
} else { | ||
$(input).on(eventName, ev); | ||
} | ||
//keep instance of the event | ||
input.inputmask.events[eventName] = input.inputmask.events[eventName] || []; | ||
input.inputmask.events[eventName].push(ev); | ||
}, | ||
off: function (input, event) { | ||
if (input.inputmask && input.inputmask.events) { | ||
const $ = input.inputmask.dependencyLib; | ||
let events = input.inputmask.events; | ||
if (event) { | ||
events = []; | ||
events[event] = input.inputmask.events[event]; | ||
} | ||
for (let eventName in events) { | ||
let evArr = events[eventName]; | ||
while (evArr.length > 0) { | ||
let ev = evArr.pop(); | ||
if (["submit", "reset",].includes(eventName)) { | ||
if (input.form !== null) $(input.form).off(eventName, ev); | ||
} else { | ||
$(input).off(eventName, ev); | ||
} | ||
} | ||
delete input.inputmask.events[eventName]; | ||
} | ||
// keep instance of the event | ||
input.inputmask.events[eventName] = input.inputmask.events[eventName] || []; | ||
input.inputmask.events[eventName].push(ev); | ||
}, | ||
off: function (input, event) { | ||
if (input.inputmask && input.inputmask.events) { | ||
const $ = input.inputmask.dependencyLib; | ||
let events = input.inputmask.events; | ||
if (event) { | ||
events = []; | ||
events[event] = input.inputmask.events[event]; | ||
} | ||
for (const eventName in events) { | ||
const evArr = events[eventName]; | ||
while (evArr.length > 0) { | ||
const ev = evArr.pop(); | ||
if (["submit", "reset"].includes(eventName)) { | ||
if (input.form !== null) $(input.form).off(eventName, ev); | ||
} else { | ||
$(input).off(eventName, ev); | ||
} | ||
} | ||
delete input.inputmask.events[eventName]; | ||
} | ||
} | ||
} | ||
}; |
@@ -7,7 +7,12 @@ /* | ||
*/ | ||
import { EventHandlers } from "../eventhandlers"; | ||
import Inputmask from "../inputmask"; | ||
import {EventHandlers} from "../eventhandlers"; | ||
import {caret, getBuffer, getLastValidPosition, translatePosition} from "../positioning"; | ||
import {getPlaceholder, getTestTemplate} from "../validation-tests"; | ||
import {keys} from "../keycode.js"; | ||
import { keys } from "../keycode.js"; | ||
import { | ||
caret, | ||
getBuffer, | ||
getLastValidPosition, | ||
translatePosition | ||
} from "../positioning"; | ||
import { getPlaceholder, getTestTemplate } from "../validation-tests"; | ||
@@ -17,12 +22,12 @@ const $ = Inputmask.dependencyLib; | ||
function Colormask(alias, options, internal) { | ||
//allow instanciating without new | ||
if (!(this instanceof Inputmask)) { | ||
return new Inputmask(alias, options, internal); | ||
} | ||
this.colorMask = undefined; | ||
Object.getOwnPropertyNames(Inputmask).forEach(function (key) { | ||
if (!Object.prototype.hasOwnProperty.call(this, key)) { | ||
this[key] = Inputmask[key]; | ||
} | ||
}, this); | ||
// allow instanciating without new | ||
if (!(this instanceof Inputmask)) { | ||
return new Inputmask(alias, options, internal); | ||
} | ||
this.colorMask = undefined; | ||
Object.getOwnPropertyNames(Inputmask).forEach(function (key) { | ||
if (!Object.prototype.hasOwnProperty.call(this, key)) { | ||
this[key] = Inputmask[key]; | ||
} | ||
}, this); | ||
} | ||
@@ -32,190 +37,234 @@ | ||
Colormask.prototype.writeBufferHook = function (caretPos) { | ||
renderColorMask.call(this, this.el, caretPos, false); | ||
renderColorMask.call(this, this.el, caretPos, false); | ||
}; | ||
Colormask.prototype.caretHook = function (caretPos) { | ||
renderColorMask.call(this, this.el, caretPos, false); | ||
renderColorMask.call(this, this.el, caretPos, false); | ||
}; | ||
Colormask.prototype.applyMaskHook = function () { | ||
initializeColorMask.call(this, this.el); | ||
initializeColorMask.call(this, this.el); | ||
}; | ||
Colormask.prototype.keyEventHook = function (e) { | ||
if (e.key === keys.ArrowRight || e.key === keys.ArrowLeft) { | ||
const inputmask = this; | ||
setTimeout(function () { | ||
var caretPos = caret.call(inputmask, inputmask.el, undefined, undefined, true); | ||
renderColorMask.call(inputmask, inputmask.el, caretPos); | ||
}, 0); | ||
} | ||
if (e.key === keys.ArrowRight || e.key === keys.ArrowLeft) { | ||
const inputmask = this; | ||
setTimeout(function () { | ||
const caretPos = caret.call( | ||
inputmask, | ||
inputmask.el, | ||
undefined, | ||
undefined, | ||
true | ||
); | ||
renderColorMask.call(inputmask, inputmask.el, caretPos); | ||
}, 0); | ||
} | ||
}; | ||
function initializeColorMask(input) { | ||
var computedStyle = (input.ownerDocument.defaultView || window).getComputedStyle(input, null); | ||
const computedStyle = ( | ||
input.ownerDocument.defaultView || window | ||
).getComputedStyle(input, null); | ||
function findCaretPos(clientx) { | ||
//calculate text width | ||
var e = document.createElement("span"), | ||
caretPos = 0; | ||
for (var style in computedStyle) { //clone styles | ||
if (isNaN(style) && style.indexOf("font") !== -1) { | ||
e.style[style] = computedStyle[style]; | ||
} | ||
} | ||
e.style.textTransform = computedStyle.textTransform; | ||
e.style.letterSpacing = computedStyle.letterSpacing; | ||
e.style.position = "absolute"; | ||
e.style.height = "auto"; | ||
e.style.width = "auto"; | ||
e.style.visibility = "hidden"; | ||
e.style.whiteSpace = "nowrap"; | ||
function findCaretPos(clientx) { | ||
// calculate text width | ||
let e = document.createElement("span"), | ||
caretPos = 0; | ||
for (const style in computedStyle) { | ||
// clone styles | ||
if (isNaN(style) && style.indexOf("font") !== -1) { | ||
e.style[style] = computedStyle[style]; | ||
} | ||
} | ||
e.style.textTransform = computedStyle.textTransform; | ||
e.style.letterSpacing = computedStyle.letterSpacing; | ||
e.style.position = "absolute"; | ||
e.style.height = "auto"; | ||
e.style.width = "auto"; | ||
e.style.visibility = "hidden"; | ||
e.style.whiteSpace = "nowrap"; | ||
document.body.appendChild(e); | ||
var inputText = input.inputmask.__valueGet.call(input), | ||
previousWidth = 0; | ||
document.body.appendChild(e); | ||
let inputText = input.inputmask.__valueGet.call(input), | ||
previousWidth = 0; | ||
while (e.offsetWidth < clientx) { | ||
var ichar = inputText.charAt(caretPos); | ||
e.innerHTML += (ichar === " " || ichar === "") ? "_" : ichar; | ||
if (e.offsetWidth >= clientx) { | ||
var offset1 = (clientx - previousWidth), | ||
offset2 = e.offsetWidth - clientx; | ||
e.innerHTML = inputText.charAt(caretPos); | ||
offset1 += Math.round(e.offsetWidth / 2); | ||
caretPos = (offset1 < offset2 ? caretPos - 1 : caretPos) - 1; | ||
break; | ||
} | ||
previousWidth = e.offsetWidth; | ||
caretPos++; | ||
} | ||
while (e.offsetWidth < clientx) { | ||
const ichar = inputText.charAt(caretPos); | ||
e.innerHTML += ichar === " " || ichar === "" ? "_" : ichar; | ||
if (e.offsetWidth >= clientx) { | ||
let offset1 = clientx - previousWidth, | ||
offset2 = e.offsetWidth - clientx; | ||
e.innerHTML = inputText.charAt(caretPos); | ||
offset1 += Math.round(e.offsetWidth / 2); | ||
caretPos = (offset1 < offset2 ? caretPos - 1 : caretPos) - 1; | ||
break; | ||
} | ||
previousWidth = e.offsetWidth; | ||
caretPos++; | ||
} | ||
if (input.style.textAlign === "right") { | ||
e.innerHTML = "_"; | ||
var maxChars = Math.ceil(input.offsetWidth / e.offsetWidth) - 1; | ||
caretPos = inputText.length - (maxChars - caretPos) + 1; | ||
} | ||
if (input.style.textAlign === "right") { | ||
e.innerHTML = "_"; | ||
const maxChars = Math.ceil(input.offsetWidth / e.offsetWidth) - 1; | ||
caretPos = inputText.length - (maxChars - caretPos) + 1; | ||
} | ||
document.body.removeChild(e); | ||
return caretPos; | ||
} | ||
document.body.removeChild(e); | ||
return caretPos; | ||
} | ||
var template = document.createElement("div"); | ||
template.style.width = computedStyle.width; | ||
template.style.textAlign = computedStyle.textAlign; | ||
let colorMask = document.createElement("div"); | ||
input.inputmask.colorMask = colorMask; | ||
colorMask.className = "im-colormask"; | ||
input.parentNode.insertBefore(colorMask, input); | ||
input.parentNode.removeChild(input); | ||
colorMask.appendChild(input); | ||
colorMask.appendChild(template); | ||
input.style.left = template.offsetLeft + "px"; | ||
const template = document.createElement("div"); | ||
template.style.width = computedStyle.width; | ||
template.style.textAlign = computedStyle.textAlign; | ||
const colorMask = document.createElement("div"); | ||
input.inputmask.colorMask = colorMask; | ||
colorMask.className = "im-colormask"; | ||
input.parentNode.insertBefore(colorMask, input); | ||
input.parentNode.removeChild(input); | ||
colorMask.appendChild(input); | ||
colorMask.appendChild(template); | ||
input.style.left = template.offsetLeft + "px"; | ||
$(colorMask).on("mouseleave", function (e) { | ||
return EventHandlers.mouseleaveEvent.call(input, [e]); | ||
}); | ||
$(colorMask).on("mouseenter", function (e) { | ||
return EventHandlers.mouseenterEvent.call(input, [e]); | ||
}); | ||
$(colorMask).on("click", function (e) { | ||
caret.call(input.inputmask, input, findCaretPos(e.clientX), undefined, true); | ||
return EventHandlers.clickEvent.call(input, [e]); | ||
}); | ||
$(colorMask).on("mouseleave", function (e) { | ||
return EventHandlers.mouseleaveEvent.call(input, [e]); | ||
}); | ||
$(colorMask).on("mouseenter", function (e) { | ||
return EventHandlers.mouseenterEvent.call(input, [e]); | ||
}); | ||
$(colorMask).on("click", function (e) { | ||
caret.call( | ||
input.inputmask, | ||
input, | ||
findCaretPos(e.clientX), | ||
undefined, | ||
true | ||
); | ||
return EventHandlers.clickEvent.call(input, [e]); | ||
}); | ||
} | ||
function positionColorMask(input, template) { | ||
input.style.left = template.offsetLeft + "px"; | ||
input.style.left = template.offsetLeft + "px"; | ||
} | ||
export function renderColorMask(input, caretPos, clear) { | ||
let inputmask = this, | ||
{isRTL, maskset, opts, maxLength} = inputmask, | ||
maskTemplate = [], | ||
isStatic = false, | ||
test, testPos, ndxIntlzr, pos = 0, | ||
templates = { | ||
static: { | ||
start: isRTL ? "</span>" : "<span class='im-static'>", | ||
end: isRTL ? "<span class='im-static'>" : "</span>" | ||
}, | ||
caret: { | ||
start: "<mark class=\"im-caret\" style=\"border-right-width: 1px;border-right-style: solid;\">", | ||
start_select: "<mark class=\"im-caret-select\">", | ||
end: "</mark>" | ||
} | ||
}; | ||
let inputmask = this, | ||
{ isRTL, maskset, opts, maxLength } = inputmask, | ||
maskTemplate = [], | ||
isStatic = false, | ||
test, | ||
testPos, | ||
ndxIntlzr, | ||
pos = 0, | ||
templates = { | ||
static: { | ||
start: isRTL ? "</span>" : "<span class='im-static'>", | ||
end: isRTL ? "<span class='im-static'>" : "</span>" | ||
}, | ||
caret: { | ||
start: | ||
'<mark class="im-caret" style="border-right-width: 1px;border-right-style: solid;">', | ||
start_select: '<mark class="im-caret-select">', | ||
end: "</mark>" | ||
} | ||
}; | ||
function setEntry(entry) { | ||
if (entry === undefined) entry = ""; | ||
if (!isStatic && (test.static === true || testPos.input === undefined)) { | ||
isStatic = true; | ||
maskTemplate.push(templates.static.start + entry); | ||
} else if (isStatic && ((test.static !== true && testPos.input !== undefined) || test.def === "")) { | ||
isStatic = false; | ||
maskTemplate.push(templates.static.end + entry); | ||
} else { | ||
maskTemplate.push(entry); | ||
} | ||
} | ||
function setEntry(entry) { | ||
if (entry === undefined) entry = ""; | ||
if (!isStatic && (test.static === true || testPos.input === undefined)) { | ||
isStatic = true; | ||
maskTemplate.push(templates.static.start + entry); | ||
} else if ( | ||
isStatic && | ||
((test.static !== true && testPos.input !== undefined) || test.def === "") | ||
) { | ||
isStatic = false; | ||
maskTemplate.push(templates.static.end + entry); | ||
} else { | ||
maskTemplate.push(entry); | ||
} | ||
} | ||
function setCaret(begin, end, length) { | ||
if (document.activeElement === input) { | ||
maskTemplate.splice(begin, 0, | ||
(begin === end || length > maskset.maskLength) ? | ||
templates.caret.start : templates.caret.start_select); | ||
maskTemplate.splice(end + (isRTL ? 0 : 1), 0, templates.caret.end); | ||
} | ||
} | ||
function setCaret(begin, end, length) { | ||
if (document.activeElement === input) { | ||
maskTemplate.splice( | ||
begin, | ||
0, | ||
begin === end || length > maskset.maskLength | ||
? templates.caret.start | ||
: templates.caret.start_select | ||
); | ||
maskTemplate.splice(end + (isRTL ? 0 : 1), 0, templates.caret.end); | ||
} | ||
} | ||
if (input.inputmask.colorMask !== undefined) { | ||
var buffer = getBuffer.call(inputmask); | ||
if (caretPos === undefined) { | ||
caretPos = caret.call(inputmask, input); | ||
} else if (caretPos.begin === undefined) { | ||
caretPos = { | ||
begin: caretPos, | ||
end: caretPos | ||
}; | ||
} | ||
if (input.inputmask.colorMask !== undefined) { | ||
const buffer = getBuffer.call(inputmask); | ||
if (caretPos === undefined) { | ||
caretPos = caret.call(inputmask, input); | ||
} else if (caretPos.begin === undefined) { | ||
caretPos = { | ||
begin: caretPos, | ||
end: caretPos | ||
}; | ||
} | ||
if (isRTL) { | ||
//translate caretPos | ||
caretPos.begin = translatePosition.call(inputmask, caretPos.begin); | ||
caretPos.end = translatePosition.call(inputmask, caretPos.end); | ||
} | ||
if (isRTL) { | ||
// translate caretPos | ||
caretPos.begin = translatePosition.call(inputmask, caretPos.begin); | ||
caretPos.end = translatePosition.call(inputmask, caretPos.end); | ||
} | ||
if (clear !== true) { | ||
var lvp = getLastValidPosition.call(inputmask); | ||
do { | ||
if (maskset.validPositions[pos]) { | ||
testPos = maskset.validPositions[pos]; | ||
test = testPos.match; | ||
ndxIntlzr = testPos.locator.slice(); | ||
setEntry(buffer[pos]); | ||
} else { | ||
testPos = getTestTemplate.call(inputmask, pos, ndxIntlzr, pos - 1); | ||
test = testPos.match; | ||
ndxIntlzr = testPos.locator.slice(); | ||
if (clear !== true) { | ||
const lvp = getLastValidPosition.call(inputmask); | ||
do { | ||
if (maskset.validPositions[pos]) { | ||
testPos = maskset.validPositions[pos]; | ||
test = testPos.match; | ||
ndxIntlzr = testPos.locator.slice(); | ||
setEntry(buffer[pos]); | ||
} else { | ||
testPos = getTestTemplate.call(inputmask, pos, ndxIntlzr, pos - 1); | ||
test = testPos.match; | ||
ndxIntlzr = testPos.locator.slice(); | ||
var jitMasking = (opts.jitMasking !== false ? opts.jitMasking : test.jit); | ||
if (jitMasking === false || jitMasking === undefined /*|| pos < lvp*/ || (typeof jitMasking === "number" && isFinite(jitMasking) && jitMasking > pos)) { | ||
setEntry(getPlaceholder.call(inputmask, pos, test)); | ||
// } else { | ||
// isStatic = false; | ||
} //break infinite loop | ||
} | ||
pos++; | ||
} while ((maxLength === undefined || pos < maxLength) && (test.static !== true || test.def !== "") || lvp > pos || isStatic); | ||
if (isStatic) setEntry(); | ||
setCaret(isRTL ? caretPos.end : caretPos.begin, isRTL ? caretPos.begin : caretPos.end, caretPos.end); | ||
} | ||
const jitMasking = | ||
opts.jitMasking !== false ? opts.jitMasking : test.jit; | ||
if ( | ||
jitMasking === false || | ||
jitMasking === undefined /* || pos < lvp */ || | ||
(typeof jitMasking === "number" && | ||
isFinite(jitMasking) && | ||
jitMasking > pos) | ||
) { | ||
setEntry(getPlaceholder.call(inputmask, pos, test)); | ||
// } else { | ||
// isStatic = false; | ||
} // break infinite loop | ||
} | ||
pos++; | ||
} while ( | ||
((maxLength === undefined || pos < maxLength) && | ||
(test.static !== true || test.def !== "")) || | ||
lvp > pos || | ||
isStatic | ||
); | ||
if (isStatic) setEntry(); | ||
setCaret( | ||
isRTL ? caretPos.end : caretPos.begin, | ||
isRTL ? caretPos.begin : caretPos.end, | ||
caretPos.end | ||
); | ||
} | ||
var template = input.inputmask.colorMask.getElementsByTagName("div")[0]; | ||
template.innerHTML = (isRTL ? maskTemplate.reverse() : maskTemplate).join(""); | ||
positionColorMask(input, template); | ||
// console.log(template.innerHTML) | ||
// console.log(JSON.stringify(caretPos)); | ||
} | ||
const template = input.inputmask.colorMask.getElementsByTagName("div")[0]; | ||
template.innerHTML = (isRTL ? maskTemplate.reverse() : maskTemplate).join( | ||
"" | ||
); | ||
positionColorMask(input, template); | ||
// console.log(template.innerHTML) | ||
// console.log(JSON.stringify(caretPos)); | ||
} | ||
} | ||
//make inputmask available | ||
// make inputmask available | ||
window.Colormask = Colormask; | ||
export default Colormask; | ||
export default Colormask; |
@@ -7,7 +7,7 @@ /* | ||
*/ | ||
import escapeRegex from "../escapeRegex"; | ||
import Inputmask from "../inputmask"; | ||
import {keyCode, keys} from "../keycode.js"; | ||
import escapeRegex from "../escapeRegex"; | ||
import {seekNext} from "../positioning"; | ||
import {getMaskTemplate, getTest} from "../validation-tests"; | ||
import { keyCode, keys } from "../keycode.js"; | ||
import { seekNext } from "../positioning"; | ||
import { getMaskTemplate, getTest } from "../validation-tests"; | ||
import "./inputmask.date.i18n"; | ||
@@ -18,611 +18,960 @@ | ||
class DateObject { | ||
constructor(mask, format, opts, inputmask) { | ||
this.mask = mask; | ||
this.format = format; | ||
this.opts = opts; | ||
this.inputmask = inputmask; | ||
this._date = new Date(1, 0, 1); | ||
this.initDateObject(mask, this.opts, this.inputmask); | ||
} | ||
constructor(mask, format, opts, inputmask) { | ||
this.mask = mask; | ||
this.format = format; | ||
this.opts = opts; | ||
this.inputmask = inputmask; | ||
this._date = new Date(1, 0, 1); | ||
this.initDateObject(mask, this.opts, this.inputmask); | ||
} | ||
get date() { | ||
if (this._date === undefined) { | ||
this._date = new Date(1, 0, 1); | ||
this.initDateObject(undefined, this.opts, this.inputmask); | ||
} | ||
return this._date; | ||
} | ||
get date() { | ||
if (this._date === undefined) { | ||
this._date = new Date(1, 0, 1); | ||
this.initDateObject(undefined, this.opts, this.inputmask); | ||
} | ||
return this._date; | ||
} | ||
initDateObject(mask, opts, inputmask) { | ||
let match; | ||
getTokenizer(opts).lastIndex = 0; | ||
while ((match = getTokenizer(opts).exec(this.format))) { | ||
let dynMatches = new RegExp("\\d+$").exec(match[0]), fcode = dynMatches ? (match[0][0] + "x") : match[0], | ||
value; | ||
if (mask !== undefined) { | ||
// console.log("mask", mask); | ||
if (dynMatches) { | ||
let lastIndex = getTokenizer(opts).lastIndex, | ||
tokenMatch = getTokenMatch.call(inputmask, match.index, opts, inputmask && inputmask.maskset); | ||
getTokenizer(opts).lastIndex = lastIndex; | ||
value = mask.slice(0, mask.indexOf(tokenMatch.nextMatch[0])); | ||
} else { | ||
let targetSymbol = match[0][0], | ||
ndx = match.index; | ||
while (inputmask && getTest.call(inputmask, ndx).match.placeholder === targetSymbol) { | ||
ndx++; | ||
} | ||
let targetMatchLength = ndx - match.index; | ||
value = mask.slice(0, targetMatchLength || (formatCode[fcode] && formatCode[fcode][4]) || fcode.length); | ||
} | ||
mask = mask.slice(value.length); | ||
} | ||
initDateObject(mask, opts, inputmask) { | ||
let match; | ||
getTokenizer(opts).lastIndex = 0; | ||
while ((match = getTokenizer(opts).exec(this.format))) { | ||
let dynMatches = /\d+$/.exec(match[0]), | ||
fcode = dynMatches ? match[0][0] + "x" : match[0], | ||
value; | ||
if (mask !== undefined) { | ||
// console.log("mask", mask); | ||
if (dynMatches) { | ||
const lastIndex = getTokenizer(opts).lastIndex, | ||
tokenMatch = getTokenMatch.call( | ||
inputmask, | ||
match.index, | ||
opts, | ||
inputmask && inputmask.maskset | ||
); | ||
getTokenizer(opts).lastIndex = lastIndex; | ||
value = mask.slice(0, mask.indexOf(tokenMatch.nextMatch[0])); | ||
} else { | ||
let targetSymbol = match[0][0], | ||
ndx = match.index; | ||
while ( | ||
inputmask && | ||
(opts.placeholder[getTest.call(inputmask, ndx).match.placeholder] || | ||
getTest.call(inputmask, ndx).match.placeholder) === targetSymbol | ||
) { | ||
ndx++; | ||
} | ||
const targetMatchLength = ndx - match.index; | ||
value = mask.slice( | ||
0, | ||
targetMatchLength || | ||
(formatCode[fcode] && formatCode[fcode][4]) || | ||
fcode.length | ||
); | ||
} | ||
mask = mask.slice(value.length); | ||
} | ||
if (Object.prototype.hasOwnProperty.call(formatCode, fcode)) { | ||
this.setValue(this, value, fcode, formatCode[fcode][2], formatCode[fcode][1]); | ||
} | ||
} | ||
} | ||
if (Object.prototype.hasOwnProperty.call(formatCode, fcode)) { | ||
this.setValue( | ||
this, | ||
value, | ||
fcode, | ||
formatCode[fcode][2], | ||
formatCode[fcode][1] | ||
); | ||
} | ||
} | ||
} | ||
setValue(dateObj, value, fcode, targetProp, dateOperation) { | ||
if (value !== undefined) { | ||
switch (targetProp) { | ||
case "ampm": | ||
dateObj[targetProp] = value; | ||
dateObj["raw" + targetProp] = value.replace(/\s/g, "_"); | ||
break; | ||
case "month": | ||
if (fcode === "mmm" || fcode === "mmmm") { | ||
fcode === "mmm" | ||
? dateObj[targetProp] = pad(i18n.monthNames.slice(0, 12).findIndex(item => value.toLowerCase() === item.toLowerCase()) + 1, 2) | ||
: dateObj[targetProp] = pad(i18n.monthNames.slice(12, 24).findIndex(item => value.toLowerCase() === item.toLowerCase()) + 1, 2); | ||
dateObj[targetProp] = dateObj[targetProp] === "00" ? "" : dateObj[targetProp].toString(); | ||
dateObj["raw" + targetProp] = dateObj[targetProp]; | ||
break; | ||
} | ||
// eslint-disable-next-line no-fallthrough | ||
default: | ||
dateObj[targetProp] = value.replace(/[^0-9]/g, "0"); | ||
dateObj["raw" + targetProp] = value.replace(/\s/g, "_"); | ||
} | ||
} | ||
if (dateOperation !== undefined) { | ||
let datavalue = dateObj[targetProp]; | ||
if ((targetProp === "day" && parseInt(datavalue) === 29) || (targetProp === "month" && parseInt(datavalue) === 2)) { | ||
if (parseInt(dateObj.day) === 29 && parseInt(dateObj.month) === 2 && (dateObj.year === "" || dateObj.year === undefined)) { | ||
//set temporary leap year in dateObj | ||
dateObj._date.setFullYear(2012, 1, 29); | ||
} | ||
} | ||
if (targetProp === "day") { | ||
useDateObject = true; | ||
if (parseInt(datavalue) === 0) datavalue = 1; | ||
} | ||
if (targetProp === "month") useDateObject = true; | ||
if (targetProp === "year") { | ||
useDateObject = true; | ||
if (datavalue.length < formatCode[fcode][4]) datavalue = pad(datavalue, formatCode[fcode][4], true); | ||
} | ||
if ((datavalue !== "" && !isNaN(datavalue)) || targetProp === "ampm") dateOperation.call(dateObj._date, datavalue); | ||
} | ||
} | ||
setValue(dateObj, value, fcode, targetProp, dateOperation) { | ||
if (value !== undefined) { | ||
switch (targetProp) { | ||
case "ampm": | ||
dateObj[targetProp] = value; | ||
dateObj["raw" + targetProp] = value.replace(/\s/g, "_"); | ||
break; | ||
case "month": | ||
if (fcode === "mmm" || fcode === "mmmm") { | ||
fcode === "mmm" | ||
? (dateObj[targetProp] = pad( | ||
i18n.monthNames | ||
.slice(0, 12) | ||
.findIndex( | ||
(item) => value.toLowerCase() === item.toLowerCase() | ||
) + 1, | ||
2 | ||
)) | ||
: (dateObj[targetProp] = pad( | ||
i18n.monthNames | ||
.slice(12, 24) | ||
.findIndex( | ||
(item) => value.toLowerCase() === item.toLowerCase() | ||
) + 1, | ||
2 | ||
)); | ||
dateObj[targetProp] = | ||
dateObj[targetProp] === "00" | ||
? "" | ||
: dateObj[targetProp].toString(); | ||
dateObj["raw" + targetProp] = dateObj[targetProp]; | ||
break; | ||
} | ||
// eslint-disable-next-line no-fallthrough | ||
default: | ||
dateObj[targetProp] = value.replace(/[^0-9]/g, "0"); | ||
dateObj["raw" + targetProp] = value.replace(/\s/g, "_"); | ||
} | ||
} | ||
if (dateOperation !== undefined) { | ||
let datavalue = dateObj[targetProp]; | ||
if ( | ||
(targetProp === "day" && parseInt(datavalue) === 29) || | ||
(targetProp === "month" && parseInt(datavalue) === 2) | ||
) { | ||
if ( | ||
parseInt(dateObj.day) === 29 && | ||
parseInt(dateObj.month) === 2 && | ||
(dateObj.year === "" || dateObj.year === undefined) | ||
) { | ||
// set temporary leap year in dateObj | ||
dateObj._date.setFullYear(2012, 1, 29); | ||
} | ||
} | ||
if (targetProp === "day") { | ||
useDateObject = true; | ||
if (parseInt(datavalue) === 0) datavalue = 1; | ||
} | ||
if (targetProp === "month") useDateObject = true; | ||
if (targetProp === "year") { | ||
useDateObject = true; | ||
if (datavalue.length < formatCode[fcode][4]) | ||
datavalue = pad(datavalue, formatCode[fcode][4], true); | ||
} | ||
if ((datavalue !== "" && !isNaN(datavalue)) || targetProp === "ampm") | ||
dateOperation.call(dateObj._date, datavalue); | ||
} | ||
} | ||
reset() { | ||
this._date = new Date(1, 0, 1); | ||
} | ||
reset() { | ||
this._date = new Date(1, 0, 1); | ||
} | ||
reInit() { | ||
this._date = undefined; | ||
this.date; | ||
} | ||
reInit() { | ||
this._date = undefined; | ||
// eslint-disable-next-line no-unused-expressions | ||
this.date; | ||
} | ||
} | ||
let currentYear = new Date().getFullYear(), i18n = Inputmask.prototype.i18n, useDateObject = false, //supported codes for formatting | ||
//http://blog.stevenlevithan.com/archives/date-time-format | ||
//https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings?view=netframework-4.7 | ||
formatCode = { //regex, valueSetter, type, displayformatter, #entries (optional) | ||
d: ["[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", Date.prototype.getDate], //Day of the month as digits; no leading zero for single-digit days. | ||
dd: ["0[1-9]|[12][0-9]|3[01]", Date.prototype.setDate, "day", function () { | ||
return pad(Date.prototype.getDate.call(this), 2); | ||
}], //Day of the month as digits; leading zero for single-digit days. | ||
ddd: [""], //Day of the week as a three-letter abbreviation. | ||
dddd: [""], //Day of the week as its full name. | ||
m: ["[1-9]|1[012]", function (val) { | ||
let mval = val ? parseInt(val) : 0; | ||
if (mval > 0) mval--; | ||
return Date.prototype.setMonth.call(this, mval); | ||
}, "month", function () { | ||
return Date.prototype.getMonth.call(this) + 1; | ||
}], //Month as digits; no leading zero for single-digit months. | ||
mm: ["0[1-9]|1[012]", function (val) { | ||
let mval = val ? parseInt(val) : 0; | ||
if (mval > 0) mval--; | ||
return Date.prototype.setMonth.call(this, mval); | ||
}, "month", function () { | ||
return pad(Date.prototype.getMonth.call(this) + 1, 2); | ||
}], //Month as digits; leading zero for single-digit months. | ||
mmm: [i18n.monthNames.slice(0, 12).join("|"), function (val) { | ||
let mval = i18n.monthNames.slice(0, 12).findIndex(item => val.toLowerCase() === item.toLowerCase()); | ||
return mval !== -1 ? Date.prototype.setMonth.call(this, mval) : false; | ||
}, "month", function () { | ||
return i18n.monthNames.slice(0, 12)[Date.prototype.getMonth.call(this)]; | ||
}],//Month as a three-letter abbreviation. | ||
mmmm: [i18n.monthNames.slice(12, 24).join("|"), function (val) { | ||
let mval = i18n.monthNames.slice(12, 24).findIndex(item => val.toLowerCase() === item.toLowerCase()); | ||
return mval !== -1 ? Date.prototype.setMonth.call(this, mval) : false; | ||
}, "month", function () { | ||
return i18n.monthNames.slice(12, 24)[Date.prototype.getMonth.call(this)]; | ||
}], //Month as its full name. | ||
yy: ["[0-9]{2}", function (val) { | ||
const centuryPart = new Date().getFullYear().toString().slice(0, 2); | ||
Date.prototype.setFullYear.call(this, `${centuryPart}${val}`); | ||
}, "year", function () { | ||
return pad(Date.prototype.getFullYear.call(this), 2); | ||
}, 2], //Year as last two digits; leading zero for years less than 10. | ||
yyyy: ["[0-9]{4}", Date.prototype.setFullYear, "year", function () { | ||
return pad(Date.prototype.getFullYear.call(this), 4); | ||
}, 4], h: ["[1-9]|1[0-2]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (12-hour clock). | ||
hh: ["0[1-9]|1[0-2]", Date.prototype.setHours, "hours", function () { | ||
return pad(Date.prototype.getHours.call(this), 2); | ||
}], //Hours; leading zero for single-digit hours (12-hour clock). | ||
hx: [function (x) { | ||
return `[0-9]{${x}}`; | ||
}, Date.prototype.setHours, "hours", function (x) { | ||
return Date.prototype.getHours; | ||
}], //Hours; no limit; set maximum digits | ||
H: ["1?[0-9]|2[0-3]", Date.prototype.setHours, "hours", Date.prototype.getHours], //Hours; no leading zero for single-digit hours (24-hour clock). | ||
HH: ["0[0-9]|1[0-9]|2[0-3]", Date.prototype.setHours, "hours", function () { | ||
return pad(Date.prototype.getHours.call(this), 2); | ||
}], //Hours; leading zero for single-digit hours (24-hour clock). | ||
Hx: [function (x) { | ||
return `[0-9]{${x}}`; | ||
}, Date.prototype.setHours, "hours", function (x) { | ||
return function () { | ||
return pad(Date.prototype.getHours.call(this), x); | ||
}; | ||
}], //Hours; no limit; set maximum digits | ||
M: ["[1-5]?[0-9]", Date.prototype.setMinutes, "minutes", Date.prototype.getMinutes], //Minutes; no leading zero for single-digit minutes. Uppercase M unlike CF timeFormat's m to avoid conflict with months. | ||
MM: ["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]", Date.prototype.setMinutes, "minutes", function () { | ||
return pad(Date.prototype.getMinutes.call(this), 2); | ||
}], //Minutes; leading zero for single-digit minutes. Uppercase MM unlike CF timeFormat's mm to avoid conflict with months. | ||
s: ["[1-5]?[0-9]", Date.prototype.setSeconds, "seconds", Date.prototype.getSeconds], //Seconds; no leading zero for single-digit seconds. | ||
ss: ["0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]", Date.prototype.setSeconds, "seconds", function () { | ||
return pad(Date.prototype.getSeconds.call(this), 2); | ||
}], //Seconds; leading zero for single-digit seconds. | ||
l: ["[0-9]{3}", Date.prototype.setMilliseconds, "milliseconds", function () { | ||
return pad(Date.prototype.getMilliseconds.call(this), 3); | ||
}, 3], //Milliseconds. 3 digits. | ||
L: ["[0-9]{2}", Date.prototype.setMilliseconds, "milliseconds", function () { | ||
return pad(Date.prototype.getMilliseconds.call(this), 2); | ||
}, 2], //Milliseconds. 2 digits. | ||
t: ["[ap]", setAMPM, "ampm", getAMPM, 1], //Lowercase, single-character time marker string: a or p. | ||
tt: ["[ap]m", setAMPM, "ampm", getAMPM, 2], //two-character time marker string: am or pm. | ||
T: ["[AP]", setAMPM, "ampm", getAMPM, 1], //single-character time marker string: A or P. | ||
TT: ["[AP]M", setAMPM, "ampm", getAMPM, 2], //two-character time marker string: AM or PM. | ||
Z: [".*", undefined, "Z", getTimeZoneAbbreviated], //US timezone abbreviation, e.g. EST or MDT. With non-US timezones or in the Opera browser, the GMT/UTC offset is returned, e.g. GMT-0500 | ||
o: [""], //GMT/UTC timezone offset, e.g. -0500 or +0230. | ||
S: [""] //The date's ordinal suffix (st, nd, rd, or th). | ||
}, formatAlias = { | ||
isoDate: "yyyy-mm-dd", //2007-06-09 | ||
isoTime: "HH:MM:ss", //17:46:21 | ||
isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", //2007-06-09T17:46:21 | ||
isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" //2007-06-09T22:46:21Z | ||
}; | ||
let currentYear = new Date().getFullYear(), | ||
i18n = Inputmask.prototype.i18n, | ||
useDateObject = false, // supported codes for formatting | ||
// http://blog.stevenlevithan.com/archives/date-time-format | ||
// https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings?view=netframework-4.7 | ||
formatCode = { | ||
// regex, valueSetter, type, displayformatter, #entries (optional) | ||
d: [ | ||
"[1-9]|[12][0-9]|3[01]", | ||
Date.prototype.setDate, | ||
"day", | ||
Date.prototype.getDate | ||
], // Day of the month as digits; no leading zero for single-digit days. | ||
dd: [ | ||
"0[1-9]|[12][0-9]|3[01]", | ||
Date.prototype.setDate, | ||
"day", | ||
function () { | ||
return pad(Date.prototype.getDate.call(this), 2); | ||
} | ||
], // Day of the month as digits; leading zero for single-digit days. | ||
ddd: [""], // Day of the week as a three-letter abbreviation. | ||
dddd: [""], // Day of the week as its full name. | ||
m: [ | ||
"[1-9]|1[012]", | ||
function (val) { | ||
let mval = val ? parseInt(val) : 0; | ||
if (mval > 0) mval--; | ||
return Date.prototype.setMonth.call(this, mval); | ||
}, | ||
"month", | ||
function () { | ||
return Date.prototype.getMonth.call(this) + 1; | ||
} | ||
], // Month as digits; no leading zero for single-digit months. | ||
mm: [ | ||
"0[1-9]|1[012]", | ||
function (val) { | ||
let mval = val ? parseInt(val) : 0; | ||
if (mval > 0) mval--; | ||
return Date.prototype.setMonth.call(this, mval); | ||
}, | ||
"month", | ||
function () { | ||
return pad(Date.prototype.getMonth.call(this) + 1, 2); | ||
} | ||
], // Month as digits; leading zero for single-digit months. | ||
mmm: [ | ||
i18n.monthNames.slice(0, 12).join("|"), | ||
function (val) { | ||
const mval = i18n.monthNames | ||
.slice(0, 12) | ||
.findIndex((item) => val.toLowerCase() === item.toLowerCase()); | ||
return mval !== -1 ? Date.prototype.setMonth.call(this, mval) : false; | ||
}, | ||
"month", | ||
function () { | ||
return i18n.monthNames.slice(0, 12)[Date.prototype.getMonth.call(this)]; | ||
} | ||
], // Month as a three-letter abbreviation. | ||
mmmm: [ | ||
i18n.monthNames.slice(12, 24).join("|"), | ||
function (val) { | ||
const mval = i18n.monthNames | ||
.slice(12, 24) | ||
.findIndex((item) => val.toLowerCase() === item.toLowerCase()); | ||
return mval !== -1 ? Date.prototype.setMonth.call(this, mval) : false; | ||
}, | ||
"month", | ||
function () { | ||
return i18n.monthNames.slice(12, 24)[ | ||
Date.prototype.getMonth.call(this) | ||
]; | ||
} | ||
], // Month as its full name. | ||
yy: [ | ||
"[0-9]{2}", | ||
function (val) { | ||
const centuryPart = new Date().getFullYear().toString().slice(0, 2); | ||
Date.prototype.setFullYear.call(this, `${centuryPart}${val}`); | ||
}, | ||
"year", | ||
function () { | ||
return pad(Date.prototype.getFullYear.call(this), 2); | ||
}, | ||
2 | ||
], // Year as last two digits; leading zero for years less than 10. | ||
yyyy: [ | ||
"[0-9]{4}", | ||
Date.prototype.setFullYear, | ||
"year", | ||
function () { | ||
return pad(Date.prototype.getFullYear.call(this), 4); | ||
}, | ||
4 | ||
], | ||
h: [ | ||
"[1-9]|1[0-2]", | ||
Date.prototype.setHours, | ||
"hours", | ||
Date.prototype.getHours | ||
], // Hours; no leading zero for single-digit hours (12-hour clock). | ||
hh: [ | ||
"0[1-9]|1[0-2]", | ||
Date.prototype.setHours, | ||
"hours", | ||
function () { | ||
return pad(Date.prototype.getHours.call(this), 2); | ||
} | ||
], // Hours; leading zero for single-digit hours (12-hour clock). | ||
hx: [ | ||
function (x) { | ||
return `[0-9]{${x}}`; | ||
}, | ||
Date.prototype.setHours, | ||
"hours", | ||
function (x) { | ||
return Date.prototype.getHours; | ||
} | ||
], // Hours; no limit; set maximum digits | ||
H: [ | ||
"1?[0-9]|2[0-3]", | ||
Date.prototype.setHours, | ||
"hours", | ||
Date.prototype.getHours | ||
], // Hours; no leading zero for single-digit hours (24-hour clock). | ||
HH: [ | ||
"0[0-9]|1[0-9]|2[0-3]", | ||
Date.prototype.setHours, | ||
"hours", | ||
function () { | ||
return pad(Date.prototype.getHours.call(this), 2); | ||
} | ||
], // Hours; leading zero for single-digit hours (24-hour clock). | ||
Hx: [ | ||
function (x) { | ||
return `[0-9]{${x}}`; | ||
}, | ||
Date.prototype.setHours, | ||
"hours", | ||
function (x) { | ||
return function () { | ||
return pad(Date.prototype.getHours.call(this), x); | ||
}; | ||
} | ||
], // Hours; no limit; set maximum digits | ||
M: [ | ||
"[1-5]?[0-9]", | ||
Date.prototype.setMinutes, | ||
"minutes", | ||
Date.prototype.getMinutes | ||
], // Minutes; no leading zero for single-digit minutes. Uppercase M unlike CF timeFormat's m to avoid conflict with months. | ||
MM: [ | ||
"0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]", | ||
Date.prototype.setMinutes, | ||
"minutes", | ||
function () { | ||
return pad(Date.prototype.getMinutes.call(this), 2); | ||
} | ||
], // Minutes; leading zero for single-digit minutes. Uppercase MM unlike CF timeFormat's mm to avoid conflict with months. | ||
s: [ | ||
"[1-5]?[0-9]", | ||
Date.prototype.setSeconds, | ||
"seconds", | ||
Date.prototype.getSeconds | ||
], // Seconds; no leading zero for single-digit seconds. | ||
ss: [ | ||
"0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]", | ||
Date.prototype.setSeconds, | ||
"seconds", | ||
function () { | ||
return pad(Date.prototype.getSeconds.call(this), 2); | ||
} | ||
], // Seconds; leading zero for single-digit seconds. | ||
l: [ | ||
"[0-9]{3}", | ||
Date.prototype.setMilliseconds, | ||
"milliseconds", | ||
function () { | ||
return pad(Date.prototype.getMilliseconds.call(this), 3); | ||
}, | ||
3 | ||
], // Milliseconds. 3 digits. | ||
L: [ | ||
"[0-9]{2}", | ||
Date.prototype.setMilliseconds, | ||
"milliseconds", | ||
function () { | ||
return pad(Date.prototype.getMilliseconds.call(this), 2); | ||
}, | ||
2 | ||
], // Milliseconds. 2 digits. | ||
t: ["[ap]", setAMPM, "ampm", getAMPM, 1], // Lowercase, single-character time marker string: a or p. | ||
tt: ["[ap]m", setAMPM, "ampm", getAMPM, 2], // two-character time marker string: am or pm. | ||
T: ["[AP]", setAMPM, "ampm", getAMPM, 1], // single-character time marker string: A or P. | ||
TT: ["[AP]M", setAMPM, "ampm", getAMPM, 2], // two-character time marker string: AM or PM. | ||
Z: [".*", undefined, "Z", getTimeZoneAbbreviated], // US timezone abbreviation, e.g. EST or MDT. With non-US timezones or in the Opera browser, the GMT/UTC offset is returned, e.g. GMT-0500 | ||
o: [""], // GMT/UTC timezone offset, e.g. -0500 or +0230. | ||
S: [""] // The date's ordinal suffix (st, nd, rd, or th). | ||
}, | ||
formatAlias = { | ||
isoDate: "yyyy-mm-dd", // 2007-06-09 | ||
isoTime: "HH:MM:ss", // 17:46:21 | ||
isoDateTime: "yyyy-mm-dd'T'HH:MM:ss", // 2007-06-09T17:46:21 | ||
isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'" // 2007-06-09T22:46:21Z | ||
}; | ||
function setAMPM(value) { | ||
const hours = this.getHours(); | ||
if (value.toLowerCase().includes("p")) { | ||
this.setHours(hours + 12); | ||
// console.log("setAMPM + 12"); | ||
} else if (value.toLowerCase().includes("a") && hours >= 12) { | ||
this.setHours(hours - 12); | ||
} | ||
const hours = this.getHours(); | ||
if (value.toLowerCase().includes("p")) { | ||
this.setHours(hours + 12); | ||
// console.log("setAMPM + 12"); | ||
} else if (value.toLowerCase().includes("a") && hours >= 12) { | ||
this.setHours(hours - 12); | ||
} | ||
} | ||
function getAMPM() { | ||
let date = this, hours = date.getHours(); | ||
hours = hours || 12; | ||
return hours >= 12 ? "PM" : "AM"; | ||
let date = this, | ||
hours = date.getHours(); | ||
hours = hours || 12; | ||
return hours >= 12 ? "PM" : "AM"; | ||
} | ||
function getTimeZoneAbbreviated() { | ||
//not perfect, but ok for now | ||
let date = this, {1: tz} = date.toString().match(/\((.+)\)/); | ||
if (tz.includes(" ")) { | ||
tz = tz.replace("-", " ").toUpperCase(); | ||
tz = tz.split(" ").map(([first]) => first).join(""); | ||
} | ||
return tz; | ||
// not perfect, but ok for now | ||
let date = this, | ||
{ 1: tz } = date.toString().match(/\((.+)\)/); | ||
if (tz.includes(" ")) { | ||
tz = tz.replace("-", " ").toUpperCase(); | ||
tz = tz | ||
.split(" ") | ||
.map(([first]) => first) | ||
.join(""); | ||
} | ||
return tz; | ||
} | ||
function formatcode(match) { | ||
var dynMatches = new RegExp("\\d+$").exec(match[0]); | ||
if (dynMatches && dynMatches[0] !== undefined) { | ||
var fcode = formatCode[match[0][0] + "x"].slice(""); | ||
fcode[0] = fcode[0](dynMatches[0]); | ||
fcode[3] = fcode[3](dynMatches[0]); | ||
const dynMatches = /\d+$/.exec(match[0]); | ||
if (dynMatches && dynMatches[0] !== undefined) { | ||
const fcode = formatCode[match[0][0] + "x"].slice(""); | ||
fcode[0] = fcode[0](dynMatches[0]); | ||
fcode[3] = fcode[3](dynMatches[0]); | ||
return fcode; | ||
} else if (formatCode[match[0]]) { | ||
return formatCode[match[0]]; | ||
} | ||
return fcode; | ||
} else if (formatCode[match[0]]) { | ||
return formatCode[match[0]]; | ||
} | ||
} | ||
function getTokenizer(opts) { | ||
if (!opts.tokenizer) { | ||
var tokens = [], dyntokens = []; | ||
for (var ndx in formatCode) { | ||
if (/\.*x$/.test(ndx)) { | ||
var dynToken = ndx[0] + "\\d+"; | ||
if (dyntokens.indexOf(dynToken) === -1) { | ||
dyntokens.push(dynToken); | ||
} | ||
} else if (tokens.indexOf(ndx[0]) === -1) { | ||
tokens.push(ndx[0]); | ||
} | ||
} | ||
opts.tokenizer = "(" + (dyntokens.length > 0 ? dyntokens.join("|") + "|" : "") + tokens.join("+|") + ")+?|."; | ||
opts.tokenizer = new RegExp(opts.tokenizer, "g"); | ||
} | ||
if (!opts.tokenizer) { | ||
const tokens = [], | ||
dyntokens = []; | ||
for (const ndx in formatCode) { | ||
if (/\.*x$/.test(ndx)) { | ||
const dynToken = ndx[0] + "\\d+"; | ||
if (dyntokens.indexOf(dynToken) === -1) { | ||
dyntokens.push(dynToken); | ||
} | ||
} else if (tokens.indexOf(ndx[0]) === -1) { | ||
tokens.push(ndx[0]); | ||
} | ||
} | ||
opts.tokenizer = | ||
"(" + | ||
(dyntokens.length > 0 ? dyntokens.join("|") + "|" : "") + | ||
tokens.join("+|") + | ||
")+?|."; | ||
opts.tokenizer = new RegExp(opts.tokenizer, "g"); | ||
} | ||
return opts.tokenizer; | ||
return opts.tokenizer; | ||
} | ||
function prefillYear(dateParts, currentResult, opts) { | ||
if (dateParts.year !== dateParts.rawyear) { | ||
var crrntyear = currentYear.toString(), enteredPart = dateParts.rawyear.replace(/[^0-9]/g, ""), | ||
currentYearPart = crrntyear.slice(0, enteredPart.length), | ||
currentYearNextPart = crrntyear.slice(enteredPart.length); | ||
if (enteredPart.length === 2 && enteredPart === currentYearPart) { | ||
const entryCurrentYear = new Date(currentYear, dateParts.month - 1, dateParts.day); | ||
if (dateParts.day == entryCurrentYear.getDate() && (!opts.max || opts.max.date.getTime() >= entryCurrentYear.getTime())) { | ||
//update dateParts | ||
dateParts.date.setFullYear(currentYear); | ||
dateParts.year = crrntyear; | ||
//update result | ||
currentResult.insert = [{ | ||
pos: currentResult.pos + 1, c: currentYearNextPart[0] | ||
}, { | ||
pos: currentResult.pos + 2, c: currentYearNextPart[1] | ||
}]; | ||
} | ||
} | ||
} | ||
if (dateParts.year !== dateParts.rawyear) { | ||
const crrntyear = currentYear.toString(), | ||
enteredPart = dateParts.rawyear.replace(/[^0-9]/g, ""), | ||
currentYearPart = crrntyear.slice(0, enteredPart.length), | ||
currentYearNextPart = crrntyear.slice(enteredPart.length); | ||
if (enteredPart.length === 2 && enteredPart === currentYearPart) { | ||
const entryCurrentYear = new Date( | ||
currentYear, | ||
dateParts.month - 1, | ||
dateParts.day | ||
); | ||
if ( | ||
dateParts.day == entryCurrentYear.getDate() && | ||
(!opts.max || opts.max.date.getTime() >= entryCurrentYear.getTime()) | ||
) { | ||
// update dateParts | ||
dateParts.date.setFullYear(currentYear); | ||
dateParts.year = crrntyear; | ||
// update result | ||
currentResult.insert = [ | ||
{ | ||
pos: currentResult.pos + 1, | ||
c: currentYearNextPart[0] | ||
}, | ||
{ | ||
pos: currentResult.pos + 2, | ||
c: currentYearNextPart[1] | ||
} | ||
]; | ||
} | ||
} | ||
} | ||
return currentResult; | ||
return currentResult; | ||
} | ||
function isValidDate(dateParts, currentResult, opts) { | ||
var inputmask = this; | ||
if (!useDateObject) return true; | ||
if (dateParts.rawday === undefined || (!isFinite(dateParts.rawday) && new Date(dateParts.date.getFullYear(), isFinite(dateParts.rawmonth) ? dateParts.month : dateParts.date.getMonth() + 1, 0).getDate() >= dateParts.day) || (dateParts.day == "29" && (!isFinite(dateParts.rawyear) || dateParts.rawyear === undefined || dateParts.rawyear === "")) || new Date(dateParts.date.getFullYear(), isFinite(dateParts.rawmonth) ? dateParts.month : dateParts.date.getMonth() + 1, 0).getDate() >= dateParts.day) { | ||
return currentResult; | ||
} else { //take corrective action if possible | ||
if (dateParts.day == "29") { | ||
var tokenMatch = getTokenMatch.call(inputmask, currentResult.pos, opts, inputmask.maskset); | ||
if (tokenMatch.targetMatch && tokenMatch.targetMatch[0] === "yyyy" && currentResult.pos - tokenMatch.targetMatchIndex === 2) { | ||
currentResult.remove = currentResult.pos + 1; | ||
return currentResult; | ||
} | ||
} else if (dateParts.date.getMonth() == 2 && dateParts.day == "30" && currentResult.c !== undefined) { | ||
dateParts.day = "03"; | ||
dateParts.date.setDate(3); | ||
dateParts.date.setMonth(1); | ||
currentResult.insert = [{pos: currentResult.pos, c: "0"}, {pos: currentResult.pos + 1, c: currentResult.c}]; | ||
currentResult.caret = seekNext.call(this, currentResult.pos + 1); | ||
return currentResult; | ||
} | ||
return false; | ||
} | ||
const inputmask = this; | ||
if (!useDateObject) return true; | ||
if ( | ||
dateParts.rawday === undefined || | ||
(!isFinite(dateParts.rawday) && | ||
new Date( | ||
dateParts.date.getFullYear(), | ||
isFinite(dateParts.rawmonth) | ||
? dateParts.month | ||
: dateParts.date.getMonth() + 1, | ||
0 | ||
).getDate() >= dateParts.day) || | ||
(dateParts.day == "29" && | ||
(!isFinite(dateParts.rawyear) || | ||
dateParts.rawyear === undefined || | ||
dateParts.rawyear === "")) || | ||
new Date( | ||
dateParts.date.getFullYear(), | ||
isFinite(dateParts.rawmonth) | ||
? dateParts.month | ||
: dateParts.date.getMonth() + 1, | ||
0 | ||
).getDate() >= dateParts.day | ||
) { | ||
return currentResult; | ||
} else { | ||
// take corrective action if possible | ||
if (dateParts.day == "29") { | ||
const tokenMatch = getTokenMatch.call( | ||
inputmask, | ||
currentResult.pos, | ||
opts, | ||
inputmask.maskset | ||
); | ||
if ( | ||
tokenMatch.targetMatch && | ||
tokenMatch.targetMatch[0] === "yyyy" && | ||
currentResult.pos - tokenMatch.targetMatchIndex === 2 | ||
) { | ||
currentResult.remove = currentResult.pos + 1; | ||
return currentResult; | ||
} | ||
} else if ( | ||
dateParts.date.getMonth() == 2 && | ||
dateParts.day == "30" && | ||
currentResult.c !== undefined | ||
) { | ||
dateParts.day = "03"; | ||
dateParts.date.setDate(3); | ||
dateParts.date.setMonth(1); | ||
currentResult.insert = [ | ||
{ pos: currentResult.pos, c: "0" }, | ||
{ pos: currentResult.pos + 1, c: currentResult.c } | ||
]; | ||
currentResult.caret = seekNext.call(this, currentResult.pos + 1); | ||
return currentResult; | ||
} | ||
return false; | ||
} | ||
} | ||
function isDateInRange(dateParts, result, opts, maskset, fromCheckval) { | ||
if (!result) return result; | ||
if (result && opts.min) { | ||
if (/*useDateObject && (dateParts["year"] === undefined || dateParts["yearSet"]) && */!isNaN(opts.min.date.getTime())) { | ||
let match; | ||
dateParts.reset(); | ||
getTokenizer(opts).lastIndex = 0; | ||
while ((match = getTokenizer(opts).exec(opts.inputFormat))) { | ||
var fcode; | ||
if ((fcode = formatcode(match))) { | ||
if (fcode[3]) { | ||
var setFn = fcode[1]; | ||
var current = dateParts[fcode[2]], minVal = opts.min[fcode[2]], | ||
maxVal = opts.max ? opts.max[fcode[2]] : minVal + 1, curVal = []; | ||
if (!result) return result; | ||
if (result && opts.min) { | ||
if ( | ||
/* useDateObject && (dateParts["year"] === undefined || dateParts["yearSet"]) && */ !isNaN( | ||
opts.min.date.getTime() | ||
) | ||
) { | ||
let match; | ||
dateParts.reset(); | ||
getTokenizer(opts).lastIndex = 0; | ||
while ((match = getTokenizer(opts).exec(opts.inputFormat))) { | ||
var fcode; | ||
if ((fcode = formatcode(match))) { | ||
if (fcode[3]) { | ||
let setFn = fcode[1], | ||
current = dateParts[fcode[2]], | ||
minVal = opts.min[fcode[2]], | ||
maxVal = opts.max ? opts.max[fcode[2]] : minVal + 1, | ||
curVal = [], | ||
forceCurrentValue = false; | ||
for (let i = 0; i < minVal.length; i++) { | ||
if ( | ||
maskset.validPositions[i + match.index] === undefined && | ||
!forceCurrentValue | ||
) { | ||
if (i + match.index == 0 && current[i] < minVal[i]) { | ||
curVal[i] = current[i]; | ||
forceCurrentValue = true; | ||
} else { | ||
curVal[i] = minVal[i]; | ||
} | ||
// ADD +1 to whole | ||
if ( | ||
fcode[2] === "year" && | ||
current.length - 1 == i && | ||
minVal != maxVal | ||
) | ||
curVal = (parseInt(curVal.join("")) + 1).toString().split(""); | ||
if ( | ||
fcode[2] === "ampm" && | ||
minVal != maxVal && | ||
opts.min.date.getTime() > dateParts.date.getTime() | ||
) | ||
curVal[i] = maxVal[i]; | ||
} else { | ||
curVal[i] = current[i]; | ||
forceCurrentValue = forceCurrentValue || current[i] > minVal[i]; | ||
} | ||
} | ||
let forceCurrentValue = false; | ||
for (let i = 0; i < minVal.length; i++) { | ||
if (maskset.validPositions[i + match.index] === undefined && !forceCurrentValue) { | ||
if (i + match.index == 0 && current[i] < minVal[i]) { | ||
curVal[i] = current[i]; | ||
forceCurrentValue = true; | ||
} else { | ||
curVal[i] = minVal[i]; | ||
} | ||
// ADD +1 to whole | ||
if (fcode[2] === "year" && current.length - 1 == i && minVal != maxVal) curVal = (parseInt(curVal.join("")) + 1).toString().split(""); | ||
if (fcode[2] === "ampm" && minVal != maxVal && opts.min.date.getTime() > dateParts.date.getTime()) curVal[i] = maxVal[i]; | ||
} else { | ||
curVal[i] = current[i]; | ||
forceCurrentValue = forceCurrentValue || current[i] > minVal[i]; | ||
} | ||
} | ||
setFn.call(dateParts._date, curVal.join("")); | ||
} | ||
} | ||
} | ||
setFn.call(dateParts._date, curVal.join("")); | ||
} | ||
} | ||
} | ||
result = opts.min.date.getTime() <= dateParts.date.getTime(); | ||
dateParts.reInit(); | ||
} | ||
} | ||
result = opts.min.date.getTime() <= dateParts.date.getTime(); | ||
dateParts.reInit(); | ||
} | ||
} | ||
if (result && opts.max) { | ||
if (!isNaN(opts.max.date.getTime())) { | ||
result = opts.max.date.getTime() >= dateParts.date.getTime(); | ||
} | ||
} | ||
return result; | ||
if (result && opts.max) { | ||
if (!isNaN(opts.max.date.getTime())) { | ||
result = opts.max.date.getTime() >= dateParts.date.getTime(); | ||
} | ||
} | ||
return result; | ||
} | ||
//parse the given format and return a mask pattern | ||
//when a dateObjValue is passed a datestring in the requested format is returned | ||
// parse the given format and return a mask pattern | ||
// when a dateObjValue is passed a datestring in the requested format is returned | ||
function parse(format, dateObjValue, opts, raw) { | ||
//parse format to regex string | ||
let mask = "", match, fcode, ndx = 0, placeHolder = {}; | ||
getTokenizer(opts).lastIndex = 0; | ||
while ((match = getTokenizer(opts).exec(format))) { | ||
if (dateObjValue === undefined) { | ||
if ((fcode = formatcode(match))) { | ||
mask += "(" + fcode[0] + ")"; | ||
placeHolder[ndx] = match[0].charAt(0); | ||
} else { | ||
switch (match[0]) { | ||
case "[": | ||
mask += "("; | ||
break; | ||
case "]": | ||
mask += ")?"; | ||
break; | ||
default: | ||
mask += escapeRegex(match[0]); | ||
placeHolder[ndx] = match[0].charAt(0); | ||
} | ||
} | ||
} else { | ||
if ((fcode = formatcode(match))) { | ||
if (raw !== true && fcode[3]) { | ||
var getFn = fcode[3]; | ||
mask += getFn.call(dateObjValue.date); | ||
} else if (fcode[2]) { | ||
mask += dateObjValue["raw" + fcode[2]]; | ||
} else { | ||
mask += match[0]; | ||
} | ||
} else { | ||
mask += match[0]; | ||
} | ||
} | ||
ndx++; | ||
} | ||
if (dateObjValue === undefined && (opts.placeholder === "" || opts.inputFormat.indexOf("mmmm") !== -1)) { | ||
opts.placeholder = placeHolder; | ||
} | ||
return mask; | ||
// parse format to regex string | ||
let mask = "", | ||
match, | ||
fcode, | ||
ndx = 0, | ||
placeHolder = {}; | ||
getTokenizer(opts).lastIndex = 0; | ||
while ((match = getTokenizer(opts).exec(format))) { | ||
if (dateObjValue === undefined) { | ||
if ((fcode = formatcode(match))) { | ||
mask += "(" + fcode[0] + ")"; | ||
// map placeholder to placeholder object and set placeholder mappings | ||
if (opts.placeholder && opts.placeholder !== "") { | ||
placeHolder[ndx] = | ||
opts.placeholder[match.index % opts.placeholder.length]; | ||
placeHolder[opts.placeholder[match.index % opts.placeholder.length]] = | ||
match[0].charAt(0); | ||
} else { | ||
placeHolder[ndx] = match[0].charAt(0); | ||
} | ||
} else { | ||
switch (match[0]) { | ||
case "[": | ||
mask += "("; | ||
break; | ||
case "]": | ||
mask += ")?"; | ||
break; | ||
default: | ||
mask += escapeRegex(match[0]); | ||
placeHolder[ndx] = match[0].charAt(0); | ||
} | ||
} | ||
} else { | ||
if ((fcode = formatcode(match))) { | ||
if (raw !== true && fcode[3]) { | ||
const getFn = fcode[3]; | ||
mask += getFn.call(dateObjValue.date); | ||
} else if (fcode[2]) { | ||
mask += dateObjValue["raw" + fcode[2]]; | ||
} else { | ||
mask += match[0]; | ||
} | ||
} else { | ||
mask += match[0]; | ||
} | ||
} | ||
ndx++; | ||
} | ||
if (dateObjValue === undefined) { | ||
opts.placeholder = placeHolder; | ||
} | ||
return mask; | ||
} | ||
//padding function | ||
// padding function | ||
function pad(val, len, right) { | ||
val = String(val); | ||
len = len || 2; | ||
while (val.length < len) val = right ? val + "0" : "0" + val; | ||
return val; | ||
val = String(val); | ||
len = len || 2; | ||
while (val.length < len) val = right ? val + "0" : "0" + val; | ||
return val; | ||
} | ||
function analyseMask(mask, format, opts) { | ||
var inputmask = this; | ||
const inputmask = this; | ||
if (typeof mask === "string") { | ||
return new DateObject(mask, format, opts, inputmask); | ||
} else if (mask && typeof mask === "object" && Object.prototype.hasOwnProperty.call(mask, "date")) { | ||
return mask; | ||
} | ||
return undefined; | ||
if (typeof mask === "string") { | ||
return new DateObject(mask, format, opts, inputmask); | ||
} else if ( | ||
mask && | ||
typeof mask === "object" && | ||
Object.prototype.hasOwnProperty.call(mask, "date") | ||
) { | ||
return mask; | ||
} | ||
return undefined; | ||
} | ||
function importDate(dateObj, opts) { | ||
return parse(opts.inputFormat, {date: dateObj}, opts); | ||
return parse(opts.inputFormat, { date: dateObj }, opts); | ||
} | ||
function getTokenMatch(pos, opts, maskset) { | ||
var inputmask = this; | ||
var masksetHint = (maskset && maskset.tests[pos]) ? maskset.tests[pos][0].match.placeholder : ""; | ||
var calcPos = 0, targetMatch, match, matchLength = 0; | ||
getTokenizer(opts).lastIndex = 0; | ||
while ((match = getTokenizer(opts).exec(opts.inputFormat))) { | ||
var dynMatches = new RegExp("\\d+$").exec(match[0]); | ||
if (dynMatches) { | ||
matchLength = parseInt(dynMatches[0]); | ||
} else { | ||
let targetSymbol = match[0][0], | ||
ndx = calcPos; | ||
while (inputmask && getTest.call(inputmask, ndx).match.placeholder === targetSymbol) { | ||
ndx++; | ||
} | ||
matchLength = ndx - calcPos; | ||
if (matchLength === 0) matchLength = match[0].length; | ||
} | ||
let inputmask = this, | ||
masksetHint = | ||
maskset && maskset.tests[pos] | ||
? opts.placeholder[maskset.tests[pos][0].match.placeholder] || | ||
maskset.tests[pos][0].match.placeholder | ||
: "", | ||
calcPos = 0, | ||
targetMatch, | ||
match, | ||
matchLength = 0; | ||
getTokenizer(opts).lastIndex = 0; | ||
while ((match = getTokenizer(opts).exec(opts.inputFormat))) { | ||
const dynMatches = /\d+$/.exec(match[0]); | ||
if (dynMatches) { | ||
matchLength = parseInt(dynMatches[0]); | ||
} else { | ||
let targetSymbol = match[0][0], | ||
ndx = calcPos; | ||
while ( | ||
inputmask && | ||
(opts.placeholder[getTest.call(inputmask, ndx).match.placeholder] || | ||
getTest.call(inputmask, ndx).match.placeholder) === targetSymbol | ||
) { | ||
ndx++; | ||
} | ||
matchLength = ndx - calcPos; | ||
if (matchLength === 0) matchLength = match[0].length; | ||
} | ||
calcPos += matchLength; | ||
if (match[0].indexOf(masksetHint) != -1 || calcPos >= pos + 1) { | ||
// console.log("gettokenmatch " + match[0] + " ~ " + (maskset ? maskset.tests[pos][0].match.placeholder : "")); | ||
targetMatch = match; | ||
match = getTokenizer(opts).exec(opts.inputFormat); | ||
break; | ||
} | ||
} | ||
return { | ||
targetMatchIndex: calcPos - matchLength, nextMatch: match, targetMatch: targetMatch | ||
}; | ||
calcPos += matchLength; | ||
if (match[0].indexOf(masksetHint) != -1 || calcPos >= pos + 1) { | ||
// console.log("gettokenmatch " + match[0] + " ~ " + (maskset ? maskset.tests[pos][0].match.placeholder : "")); | ||
targetMatch = match; | ||
match = getTokenizer(opts).exec(opts.inputFormat); | ||
break; | ||
} | ||
} | ||
return { | ||
targetMatchIndex: calcPos - matchLength, | ||
nextMatch: match, | ||
targetMatch | ||
}; | ||
} | ||
Inputmask.extendAliases({ | ||
"datetime": { | ||
mask: function (opts) { | ||
//do not allow numeric input in datetime alias | ||
opts.numericInput = false; | ||
datetime: { | ||
mask: function (opts) { | ||
// do not allow numeric input in datetime alias | ||
opts.numericInput = false; | ||
//localize | ||
formatCode.S = i18n.ordinalSuffix.join("|"); | ||
// localize | ||
formatCode.S = i18n.ordinalSuffix.join("|"); | ||
opts.inputFormat = formatAlias[opts.inputFormat] || opts.inputFormat; //resolve possible formatAlias | ||
opts.displayFormat = formatAlias[opts.displayFormat] || opts.displayFormat || opts.inputFormat; //resolve possible formatAlias | ||
opts.outputFormat = formatAlias[opts.outputFormat] || opts.outputFormat || opts.inputFormat; //resolve possible formatAlias | ||
// opts.placeholder = opts.placeholder !== "" ? opts.placeholder : opts.inputFormat.replace(/[[\]]/, ""); | ||
opts.regex = parse(opts.inputFormat, undefined, opts); | ||
opts.min = analyseMask(opts.min, opts.inputFormat, opts); | ||
opts.max = analyseMask(opts.max, opts.inputFormat, opts); | ||
return null; //migrate to regex mask | ||
}, | ||
placeholder: "", //set default as none (~ auto); when a custom placeholder is passed it will be used | ||
inputFormat: "isoDateTime", //format used to input the date | ||
displayFormat: null, //visual format when the input looses focus | ||
outputFormat: null, //unmasking format | ||
min: null, //needs to be in the same format as the inputfornat | ||
max: null, //needs to be in the same format as the inputfornat, | ||
skipOptionalPartCharacter: "", | ||
preValidation: function (buffer, pos, c, isSelection, opts, maskset, caretPos, strict) { | ||
const inputmask = this; | ||
if (strict) return true; | ||
if (isNaN(c) && buffer[pos] !== c) { | ||
var tokenMatch = getTokenMatch.call(inputmask, pos, opts, maskset); | ||
if (tokenMatch.nextMatch && tokenMatch.nextMatch[0] === c && tokenMatch.targetMatch[0].length > 1) { | ||
var validator = formatcode(tokenMatch.targetMatch)[0]; | ||
if (new RegExp(validator).test("0" + buffer[pos - 1])) { | ||
buffer[pos] = buffer[pos - 1]; | ||
buffer[pos - 1] = "0"; | ||
return { | ||
fuzzy: true, buffer: buffer, refreshFromBuffer: {start: pos - 1, end: pos + 1}, pos: pos + 1 | ||
}; | ||
} | ||
} | ||
} | ||
return true; | ||
}, | ||
postValidation: function (buffer, pos, c, currentResult, opts, maskset, strict, fromCheckval) { | ||
const inputmask = this; | ||
opts.inputFormat = formatAlias[opts.inputFormat] || opts.inputFormat; // resolve possible formatAlias | ||
opts.displayFormat = | ||
formatAlias[opts.displayFormat] || | ||
opts.displayFormat || | ||
opts.inputFormat; // resolve possible formatAlias | ||
opts.outputFormat = | ||
formatAlias[opts.outputFormat] || opts.outputFormat || opts.inputFormat; // resolve possible formatAlias | ||
// opts.placeholder = opts.placeholder !== "" ? opts.placeholder : opts.inputFormat.replace(/[[\]]/, ""); | ||
opts.regex = parse(opts.inputFormat, undefined, opts); | ||
opts.min = analyseMask(opts.min, opts.inputFormat, opts); | ||
opts.max = analyseMask(opts.max, opts.inputFormat, opts); | ||
return null; // migrate to regex mask | ||
}, | ||
placeholder: "", // set default as none (~ auto); when a custom placeholder is passed it will be used | ||
inputFormat: "isoDateTime", // format used to input the date | ||
displayFormat: null, // visual format when the input looses focus | ||
outputFormat: null, // unmasking format | ||
min: null, // needs to be in the same format as the inputfornat | ||
max: null, // needs to be in the same format as the inputfornat, | ||
skipOptionalPartCharacter: "", | ||
preValidation: function ( | ||
buffer, | ||
pos, | ||
c, | ||
isSelection, | ||
opts, | ||
maskset, | ||
caretPos, | ||
strict | ||
) { | ||
const inputmask = this; | ||
if (strict) return true; | ||
if (isNaN(c) && buffer[pos] !== c) { | ||
const tokenMatch = getTokenMatch.call(inputmask, pos, opts, maskset); | ||
if ( | ||
tokenMatch.nextMatch && | ||
tokenMatch.nextMatch[0] === c && | ||
tokenMatch.targetMatch[0].length > 1 | ||
) { | ||
const validator = formatcode(tokenMatch.targetMatch)[0]; | ||
if (new RegExp(validator).test("0" + buffer[pos - 1])) { | ||
buffer[pos] = buffer[pos - 1]; | ||
buffer[pos - 1] = "0"; | ||
return { | ||
fuzzy: true, | ||
buffer, | ||
refreshFromBuffer: { start: pos - 1, end: pos + 1 }, | ||
pos: pos + 1 | ||
}; | ||
} | ||
} | ||
} | ||
return true; | ||
}, | ||
postValidation: function ( | ||
buffer, | ||
pos, | ||
c, | ||
currentResult, | ||
opts, | ||
maskset, | ||
strict, | ||
fromCheckval | ||
) { | ||
const inputmask = this; | ||
if (strict) return true; | ||
var tokenMatch, validator; | ||
if (currentResult === false) { //try some shifting | ||
tokenMatch = getTokenMatch.call(inputmask, pos + 1, opts, maskset); | ||
if (tokenMatch.targetMatch && tokenMatch.targetMatchIndex === pos && tokenMatch.targetMatch[0].length > 1 && formatCode[tokenMatch.targetMatch[0]] !== undefined) { | ||
validator = formatcode(tokenMatch.targetMatch)[0]; | ||
} else { | ||
tokenMatch = getTokenMatch.call(inputmask, pos + 2, opts, maskset); | ||
if (tokenMatch.targetMatch && tokenMatch.targetMatchIndex === pos + 1 && tokenMatch.targetMatch[0].length > 1 && formatCode[tokenMatch.targetMatch[0]] !== undefined) { | ||
validator = formatcode(tokenMatch.targetMatch)[0]; | ||
} | ||
} | ||
if (validator !== undefined) { | ||
if (maskset.validPositions[pos + 1] !== undefined && new RegExp(validator).test(c + "0")) { | ||
buffer[pos] = c; | ||
buffer[pos + 1] = "0"; | ||
currentResult = { | ||
//insert: [{pos: pos, c: "0"}, {pos: pos + 1, c: c}], | ||
pos: pos + 2, //this will triggeer a refreshfrombuffer | ||
caret: pos | ||
}; | ||
} else if (new RegExp(validator).test("0" + c)) { | ||
buffer[pos] = "0"; | ||
buffer[pos + 1] = c; | ||
currentResult = { | ||
//insert: [{pos: pos, c: "0"}, {pos: pos + 1, c: c}], | ||
pos: pos + 2 //this will triggeer a refreshfrombuffer | ||
}; | ||
} | ||
} | ||
if (strict) return true; | ||
let tokenMatch, validator; | ||
if (currentResult === false) { | ||
// try some shifting | ||
tokenMatch = getTokenMatch.call(inputmask, pos + 1, opts, maskset); | ||
if ( | ||
tokenMatch.targetMatch && | ||
tokenMatch.targetMatchIndex === pos && | ||
tokenMatch.targetMatch[0].length > 1 && | ||
formatCode[tokenMatch.targetMatch[0]] !== undefined | ||
) { | ||
validator = formatcode(tokenMatch.targetMatch)[0]; | ||
} else { | ||
tokenMatch = getTokenMatch.call(inputmask, pos + 2, opts, maskset); | ||
if ( | ||
tokenMatch.targetMatch && | ||
tokenMatch.targetMatchIndex === pos + 1 && | ||
tokenMatch.targetMatch[0].length > 1 && | ||
formatCode[tokenMatch.targetMatch[0]] !== undefined | ||
) { | ||
validator = formatcode(tokenMatch.targetMatch)[0]; | ||
} | ||
} | ||
if (validator !== undefined) { | ||
if ( | ||
maskset.validPositions[pos + 1] !== undefined && | ||
new RegExp(validator).test(c + "0") | ||
) { | ||
buffer[pos] = c; | ||
buffer[pos + 1] = "0"; | ||
currentResult = { | ||
// insert: [{pos: pos, c: "0"}, {pos: pos + 1, c: c}], | ||
pos: pos + 2, // this will triggeer a refreshfrombuffer | ||
caret: pos | ||
}; | ||
} else if (new RegExp(validator).test("0" + c)) { | ||
buffer[pos] = "0"; | ||
buffer[pos + 1] = c; | ||
currentResult = { | ||
// insert: [{pos: pos, c: "0"}, {pos: pos + 1, c: c}], | ||
pos: pos + 2 // this will triggeer a refreshfrombuffer | ||
}; | ||
} | ||
} | ||
if (currentResult === false) return currentResult; | ||
} | ||
if (currentResult === false) return currentResult; | ||
} | ||
if (currentResult.fuzzy) { | ||
buffer = currentResult.buffer; | ||
pos = currentResult.pos; | ||
} | ||
if (currentResult.fuzzy) { | ||
buffer = currentResult.buffer; | ||
pos = currentResult.pos; | ||
} | ||
//full validate target | ||
tokenMatch = getTokenMatch.call(inputmask, pos, opts, maskset); | ||
if (tokenMatch.targetMatch && tokenMatch.targetMatch[0] && formatCode[tokenMatch.targetMatch[0]] !== undefined) { | ||
let fcode = formatcode(tokenMatch.targetMatch); | ||
validator = fcode[0]; | ||
var part = buffer.slice(tokenMatch.targetMatchIndex, tokenMatch.targetMatchIndex + tokenMatch.targetMatch[0].length); | ||
if (new RegExp(validator).test(part.join("")) === false && tokenMatch.targetMatch[0].length === 2 && maskset.validPositions[tokenMatch.targetMatchIndex] && maskset.validPositions[tokenMatch.targetMatchIndex + 1]) { | ||
maskset.validPositions[tokenMatch.targetMatchIndex + 1].input = "0"; | ||
} | ||
if (fcode[2] == "year") { | ||
var _buffer = getMaskTemplate.call(inputmask, false, 1, undefined, true); | ||
for (let i = pos + 1; i < buffer.length; i++) { | ||
buffer[i] = _buffer[i]; | ||
maskset.validPositions.splice(pos + 1, 1); | ||
} | ||
} | ||
} | ||
// full validate target | ||
tokenMatch = getTokenMatch.call(inputmask, pos, opts, maskset); | ||
if ( | ||
tokenMatch.targetMatch && | ||
tokenMatch.targetMatch[0] && | ||
formatCode[tokenMatch.targetMatch[0]] !== undefined | ||
) { | ||
const fcode = formatcode(tokenMatch.targetMatch); | ||
validator = fcode[0]; | ||
const part = buffer.slice( | ||
tokenMatch.targetMatchIndex, | ||
tokenMatch.targetMatchIndex + tokenMatch.targetMatch[0].length | ||
); | ||
if ( | ||
new RegExp(validator).test(part.join("")) === false && | ||
tokenMatch.targetMatch[0].length === 2 && | ||
maskset.validPositions[tokenMatch.targetMatchIndex] && | ||
maskset.validPositions[tokenMatch.targetMatchIndex + 1] | ||
) { | ||
maskset.validPositions[tokenMatch.targetMatchIndex + 1].input = "0"; | ||
} | ||
if (fcode[2] == "year") { | ||
const _buffer = getMaskTemplate.call( | ||
inputmask, | ||
false, | ||
1, | ||
undefined, | ||
true | ||
); | ||
for (let i = pos + 1; i < buffer.length; i++) { | ||
buffer[i] = _buffer[i]; | ||
maskset.validPositions.splice(pos + 1, 1); | ||
} | ||
} | ||
} | ||
var result = currentResult, | ||
dateParts = analyseMask.call(inputmask, buffer.join(""), opts.inputFormat, opts); | ||
if (result && !isNaN(dateParts.date.getTime())) { //check for a valid date ~ an invalid date returns NaN which isn't equal | ||
if (opts.prefillYear) result = prefillYear(dateParts, result, opts); | ||
result = isValidDate.call(inputmask, dateParts, result, opts); | ||
result = isDateInRange(dateParts, result, opts, maskset, fromCheckval); | ||
} | ||
let result = currentResult, | ||
dateParts = analyseMask.call( | ||
inputmask, | ||
buffer.join(""), | ||
opts.inputFormat, | ||
opts | ||
); | ||
if (result && !isNaN(dateParts.date.getTime())) { | ||
// check for a valid date ~ an invalid date returns NaN which isn't equal | ||
if (opts.prefillYear) result = prefillYear(dateParts, result, opts); | ||
result = isValidDate.call(inputmask, dateParts, result, opts); | ||
result = isDateInRange(dateParts, result, opts, maskset, fromCheckval); | ||
} | ||
if (pos !== undefined && result && currentResult.pos !== pos) { | ||
return { | ||
buffer: parse(opts.inputFormat, dateParts, opts).split(""), | ||
refreshFromBuffer: {start: pos, end: currentResult.pos}, | ||
pos: currentResult.caret || currentResult.pos //correct caret position | ||
}; | ||
} | ||
if (pos !== undefined && result && currentResult.pos !== pos) { | ||
return { | ||
buffer: parse(opts.inputFormat, dateParts, opts).split(""), | ||
refreshFromBuffer: { start: pos, end: currentResult.pos }, | ||
pos: currentResult.caret || currentResult.pos // correct caret position | ||
}; | ||
} | ||
return result; | ||
}, | ||
onKeyDown: function (e, buffer, caretPos, opts) { | ||
var input = this; | ||
if (e.ctrlKey && e.key === keys.ArrowRight) { | ||
input.inputmask._valueSet(importDate(new Date(), opts)); | ||
$(input).trigger("setvalue"); | ||
} | ||
}, | ||
onUnMask: function (maskedValue, unmaskedValue, opts) { | ||
var inputmask = this; | ||
return unmaskedValue ? parse(opts.outputFormat, analyseMask.call(inputmask, maskedValue, opts.inputFormat, opts), opts, true) : unmaskedValue; | ||
}, | ||
casing: function (elem, test, pos, validPositions) { | ||
if (test.nativeDef.indexOf("[ap]") == 0) return elem.toLowerCase(); | ||
if (test.nativeDef.indexOf("[AP]") == 0) return elem.toUpperCase(); | ||
return result; | ||
}, | ||
onKeyDown: function (e, buffer, caretPos, opts) { | ||
const input = this; | ||
if (e.ctrlKey && e.key === keys.ArrowRight) { | ||
input.inputmask._valueSet(importDate(new Date(), opts)); | ||
$(input).trigger("setvalue"); | ||
} | ||
}, | ||
onUnMask: function (maskedValue, unmaskedValue, opts) { | ||
const inputmask = this; | ||
return unmaskedValue | ||
? parse( | ||
opts.outputFormat, | ||
analyseMask.call(inputmask, maskedValue, opts.inputFormat, opts), | ||
opts, | ||
true | ||
) | ||
: unmaskedValue; | ||
}, | ||
casing: function (elem, test, pos, validPositions) { | ||
if (test.nativeDef.indexOf("[ap]") == 0) return elem.toLowerCase(); | ||
if (test.nativeDef.indexOf("[AP]") == 0) return elem.toUpperCase(); | ||
let posBefore = getTest.call(this, [pos - 1]); | ||
if (pos === 0 || posBefore && posBefore.input === String.fromCharCode(keyCode.Space) || posBefore && posBefore.match.def === String.fromCharCode(keyCode.Space)) { | ||
return elem.toUpperCase(); | ||
} | ||
return elem.toLowerCase(); | ||
}, | ||
onBeforeMask: function (initialValue, opts) { | ||
if (Object.prototype.toString.call(initialValue) === "[object Date]") { | ||
initialValue = importDate(initialValue, opts); | ||
} | ||
const posBefore = getTest.call(this, [pos - 1]); | ||
if ( | ||
pos === 0 || | ||
(posBefore && posBefore.input === String.fromCharCode(keyCode.Space)) || | ||
(posBefore && | ||
posBefore.match.def === String.fromCharCode(keyCode.Space)) | ||
) { | ||
return elem.toUpperCase(); | ||
} | ||
return elem.toLowerCase(); | ||
}, | ||
onBeforeMask: function (initialValue, opts) { | ||
if (Object.prototype.toString.call(initialValue) === "[object Date]") { | ||
initialValue = importDate(initialValue, opts); | ||
} | ||
return initialValue; | ||
}, | ||
insertMode: false, | ||
insertModeVisual: false, | ||
shiftPositions: false, | ||
keepStatic: false, | ||
inputmode: "numeric", | ||
prefillYear: true //Allows to disable prefill for datetime year. | ||
} | ||
return initialValue; | ||
}, | ||
insertMode: false, | ||
insertModeVisual: false, | ||
shiftPositions: false, | ||
keepStatic: false, | ||
inputmode: "numeric", | ||
prefillYear: true // Allows to disable prefill for datetime year. | ||
} | ||
}); |
@@ -12,10 +12,45 @@ /* | ||
$.extend(true, Inputmask.prototype.i18n, { | ||
dayNames: [ | ||
"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", | ||
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" | ||
], | ||
monthNames: [ | ||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", | ||
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" | ||
], ordinalSuffix: ["st", "nd", "rd", "th"] | ||
}); | ||
dayNames: [ | ||
"Mon", | ||
"Tue", | ||
"Wed", | ||
"Thu", | ||
"Fri", | ||
"Sat", | ||
"Sun", | ||
"Monday", | ||
"Tuesday", | ||
"Wednesday", | ||
"Thursday", | ||
"Friday", | ||
"Saturday", | ||
"Sunday" | ||
], | ||
monthNames: [ | ||
"Jan", | ||
"Feb", | ||
"Mar", | ||
"Apr", | ||
"May", | ||
"Jun", | ||
"Jul", | ||
"Aug", | ||
"Sep", | ||
"Oct", | ||
"Nov", | ||
"Dec", | ||
"January", | ||
"February", | ||
"March", | ||
"April", | ||
"May", | ||
"June", | ||
"July", | ||
"August", | ||
"September", | ||
"October", | ||
"November", | ||
"December" | ||
], | ||
ordinalSuffix: ["st", "nd", "rd", "th"] | ||
}); |
@@ -8,109 +8,159 @@ /* | ||
import Inputmask from "../inputmask"; | ||
import {getLastValidPosition} from "../positioning"; | ||
import {getMaskTemplate} from "../validation-tests"; | ||
//extra definitions | ||
import { getLastValidPosition } from "../positioning"; | ||
import { getMaskTemplate } from "../validation-tests"; | ||
// extra definitions | ||
Inputmask.extendDefinitions({ | ||
"A": { | ||
validator: "[A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]", casing: "upper" //auto uppercasing | ||
}, "&": { //alfanumeric uppercasing | ||
validator: "[0-9A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]", casing: "upper" | ||
}, "#": { //hexadecimal | ||
validator: "[0-9A-Fa-f]", casing: "upper" | ||
} | ||
A: { | ||
validator: "[A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]", | ||
casing: "upper" // auto uppercasing | ||
}, | ||
"&": { | ||
// alfanumeric uppercasing | ||
validator: "[0-9A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5]", | ||
casing: "upper" | ||
}, | ||
"#": { | ||
// hexadecimal | ||
validator: "[0-9A-Fa-f]", | ||
casing: "upper" | ||
} | ||
}); | ||
var ipValidatorRegex = new RegExp("25[0-5]|2[0-4][0-9]|[01][0-9][0-9]"); | ||
const ipValidatorRegex = /25[0-5]|2[0-4][0-9]|[01][0-9][0-9]/; | ||
function ipValidator(chrs, maskset, pos, strict, opts) { | ||
if (pos - 1 > -1 && maskset.buffer[pos - 1] !== ".") { | ||
chrs = maskset.buffer[pos - 1] + chrs; | ||
if (pos - 2 > -1 && maskset.buffer[pos - 2] !== ".") { | ||
chrs = maskset.buffer[pos - 2] + chrs; | ||
} else chrs = "0" + chrs; | ||
} else chrs = "00" + chrs; | ||
if (opts.greedy && parseInt(chrs) > 255 && ipValidatorRegex.test("00" + chrs.charAt(2))) { | ||
var buffer = [...maskset.buffer.slice(0, pos), ".", chrs.charAt(2)]; | ||
if (buffer.join("").match(/\./g).length < 4) { | ||
return { | ||
refreshFromBuffer: true, | ||
buffer: buffer, | ||
caret: pos + 2 | ||
}; | ||
} | ||
} | ||
return ipValidatorRegex.test(chrs); | ||
if (pos - 1 > -1 && maskset.buffer[pos - 1] !== ".") { | ||
chrs = maskset.buffer[pos - 1] + chrs; | ||
if (pos - 2 > -1 && maskset.buffer[pos - 2] !== ".") { | ||
chrs = maskset.buffer[pos - 2] + chrs; | ||
} else chrs = "0" + chrs; | ||
} else chrs = "00" + chrs; | ||
if ( | ||
opts.greedy && | ||
parseInt(chrs) > 255 && | ||
ipValidatorRegex.test("00" + chrs.charAt(2)) | ||
) { | ||
const buffer = [...maskset.buffer.slice(0, pos), ".", chrs.charAt(2)]; | ||
if (buffer.join("").match(/\./g).length < 4) { | ||
return { | ||
refreshFromBuffer: true, | ||
buffer, | ||
caret: pos + 2 | ||
}; | ||
} | ||
} | ||
return ipValidatorRegex.test(chrs); | ||
} | ||
Inputmask.extendAliases({ | ||
"cssunit": { | ||
regex: "[+-]?[0-9]+\\.?([0-9]+)?(px|em|rem|ex|%|in|cm|mm|pt|pc)" | ||
}, "url": { //needs update => https://en.wikipedia.org/wiki/URL | ||
regex: "(https?|ftp)://.*", autoUnmask: false, keepStatic: false, tabThrough: true | ||
}, "ip": { //ip-address mask | ||
mask: "i{1,3}.j{1,3}.k{1,3}.l{1,3}", definitions: { | ||
"i": { | ||
validator: ipValidator | ||
}, "j": { | ||
validator: ipValidator | ||
}, "k": { | ||
validator: ipValidator | ||
}, "l": { | ||
validator: ipValidator | ||
} | ||
}, onUnMask: function (maskedValue, unmaskedValue, opts) { | ||
return maskedValue; | ||
}, inputmode: "decimal", substitutes: {",": "."} | ||
}, "email": { | ||
//https://en.wikipedia.org/wiki/Domain_name#Domain_name_space | ||
//https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names | ||
//should be extended with the toplevel domains at the end | ||
mask: function ({separator, quantifier}) { | ||
var emailMask = "*{1,64}[.*{1,64}][.*{1,64}][.*{1,63}]@-{1,63}.-{1,63}[.-{1,63}][.-{1,63}]"; | ||
var mask = emailMask; | ||
if (separator) { | ||
for (let i = 0; i < quantifier; i++) { | ||
mask += `[${separator}${emailMask}]`; | ||
} | ||
} | ||
return mask; | ||
}, | ||
greedy: false, | ||
casing: "lower", | ||
separator: null, | ||
quantifier: 5, | ||
skipOptionalPartCharacter: "", | ||
onBeforePaste: function (pastedValue, opts) { | ||
pastedValue = pastedValue.toLowerCase(); | ||
return pastedValue.replace("mailto:", ""); | ||
}, | ||
definitions: { | ||
"*": { | ||
validator: "[0-9\uFF11-\uFF19A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5!#$%&'*+/=?^_`{|}~-]" | ||
}, "-": { | ||
validator: "[0-9A-Za-z-]" | ||
} | ||
}, | ||
onUnMask: function (maskedValue, unmaskedValue, opts) { | ||
return maskedValue; | ||
}, | ||
inputmode: "email" | ||
}, "mac": { | ||
mask: "##:##:##:##:##:##" | ||
}, //https://en.wikipedia.org/wiki/Vehicle_identification_number | ||
// see issue #1199 | ||
"vin": { | ||
mask: "V{13}9{4}", definitions: { | ||
"V": { | ||
validator: "[A-HJ-NPR-Za-hj-npr-z\\d]", casing: "upper" | ||
} | ||
}, clearIncomplete: true, autoUnmask: true | ||
}, //http://rion.io/2013/09/10/validating-social-security-numbers-through-regular-expressions-2/ | ||
//https://en.wikipedia.org/wiki/Social_Security_number | ||
"ssn": { | ||
mask: "999-99-9999", postValidation: function (buffer, pos, c, currentResult, opts, maskset, strict) { | ||
var bffr = getMaskTemplate.call(this, true, getLastValidPosition.call(this), true, true); | ||
return /^(?!219-09-9999|078-05-1120)(?!666|000|9.{2}).{3}-(?!00).{2}-(?!0{4}).{4}$/.test(bffr.join("")); | ||
} | ||
}, | ||
cssunit: { | ||
regex: "[+-]?[0-9]+\\.?([0-9]+)?(px|em|rem|ex|%|in|cm|mm|pt|pc)" | ||
}, | ||
url: { | ||
// needs update => https://en.wikipedia.org/wiki/URL | ||
regex: "(https?|ftp)://.*", | ||
autoUnmask: false, | ||
keepStatic: false, | ||
tabThrough: true | ||
}, | ||
ip: { | ||
// ip-address mask | ||
mask: "i{1,3}.j{1,3}.k{1,3}.l{1,3}", | ||
definitions: { | ||
i: { | ||
validator: ipValidator | ||
}, | ||
j: { | ||
validator: ipValidator | ||
}, | ||
k: { | ||
validator: ipValidator | ||
}, | ||
l: { | ||
validator: ipValidator | ||
} | ||
}, | ||
onUnMask: function (maskedValue, unmaskedValue, opts) { | ||
return maskedValue; | ||
}, | ||
inputmode: "decimal", | ||
substitutes: { ",": "." } | ||
}, | ||
email: { | ||
// https://en.wikipedia.org/wiki/Domain_name#Domain_name_space | ||
// https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names | ||
// should be extended with the toplevel domains at the end | ||
mask: function ({ separator, quantifier }) { | ||
let emailMask = | ||
"*{1,64}[.*{1,64}][.*{1,64}][.*{1,63}]@-{1,63}.-{1,63}[.-{1,63}][.-{1,63}]", | ||
mask = emailMask; | ||
if (separator) { | ||
for (let i = 0; i < quantifier; i++) { | ||
mask += `[${separator}${emailMask}]`; | ||
} | ||
} | ||
return mask; | ||
}, | ||
greedy: false, | ||
casing: "lower", | ||
separator: null, | ||
quantifier: 5, | ||
skipOptionalPartCharacter: "", | ||
onBeforePaste: function (pastedValue, opts) { | ||
pastedValue = pastedValue.toLowerCase(); | ||
return pastedValue.replace("mailto:", ""); | ||
}, | ||
definitions: { | ||
"*": { | ||
validator: | ||
"[0-9\uFF11-\uFF19A-Za-z\u0410-\u044F\u0401\u0451\u00C0-\u00FF\u00B5!#$%&'*+/=?^_`{|}~-]" | ||
}, | ||
"-": { | ||
validator: "[0-9A-Za-z-]" | ||
} | ||
}, | ||
onUnMask: function (maskedValue, unmaskedValue, opts) { | ||
return maskedValue; | ||
}, | ||
inputmode: "email" | ||
}, | ||
mac: { | ||
mask: "##:##:##:##:##:##" | ||
}, // https://en.wikipedia.org/wiki/Vehicle_identification_number | ||
// see issue #1199 | ||
vin: { | ||
mask: "V{13}9{4}", | ||
definitions: { | ||
V: { | ||
validator: "[A-HJ-NPR-Za-hj-npr-z\\d]", | ||
casing: "upper" | ||
} | ||
}, | ||
clearIncomplete: true, | ||
autoUnmask: true | ||
}, // http://rion.io/2013/09/10/validating-social-security-numbers-through-regular-expressions-2/ | ||
// https://en.wikipedia.org/wiki/Social_Security_number | ||
ssn: { | ||
mask: "999-99-9999", | ||
postValidation: function ( | ||
buffer, | ||
pos, | ||
c, | ||
currentResult, | ||
opts, | ||
maskset, | ||
strict | ||
) { | ||
const bffr = getMaskTemplate.call( | ||
this, | ||
true, | ||
getLastValidPosition.call(this), | ||
true, | ||
true | ||
); | ||
return /^(?!219-09-9999|078-05-1120)(?!666|000|9.{2}).{3}-(?!00).{2}-(?!0{4}).{4}$/.test( | ||
bffr.join("") | ||
); | ||
} | ||
} | ||
}); |
@@ -7,6 +7,6 @@ /* | ||
*/ | ||
import escapeRegex from "../escapeRegex"; | ||
import Inputmask from "../inputmask"; | ||
import escapeRegex from "../escapeRegex"; | ||
import {seekNext} from "../positioning"; | ||
import {keys} from "../keycode"; | ||
import { keys } from "../keycode"; | ||
import { seekNext } from "../positioning"; | ||
@@ -16,634 +16,896 @@ const $ = Inputmask.dependencyLib; | ||
function autoEscape(txt, opts) { | ||
var escapedTxt = ""; | ||
for (var i = 0; i < txt.length; i++) { | ||
if (Inputmask.prototype.definitions[txt.charAt(i)] || | ||
opts.definitions[txt.charAt(i)] || | ||
opts.optionalmarker[0] === txt.charAt(i) || | ||
opts.optionalmarker[1] === txt.charAt(i) || | ||
opts.quantifiermarker[0] === txt.charAt(i) || | ||
opts.quantifiermarker[1] === txt.charAt(i) || | ||
opts.groupmarker[0] === txt.charAt(i) || | ||
opts.groupmarker[1] === txt.charAt(i) || | ||
opts.alternatormarker === txt.charAt(i)) { | ||
escapedTxt += "\\" + txt.charAt(i); | ||
} else { | ||
escapedTxt += txt.charAt(i); | ||
} | ||
} | ||
return escapedTxt; | ||
let escapedTxt = ""; | ||
for (let i = 0; i < txt.length; i++) { | ||
if ( | ||
Inputmask.prototype.definitions[txt.charAt(i)] || | ||
opts.definitions[txt.charAt(i)] || | ||
opts.optionalmarker[0] === txt.charAt(i) || | ||
opts.optionalmarker[1] === txt.charAt(i) || | ||
opts.quantifiermarker[0] === txt.charAt(i) || | ||
opts.quantifiermarker[1] === txt.charAt(i) || | ||
opts.groupmarker[0] === txt.charAt(i) || | ||
opts.groupmarker[1] === txt.charAt(i) || | ||
opts.alternatormarker === txt.charAt(i) | ||
) { | ||
escapedTxt += "\\" + txt.charAt(i); | ||
} else { | ||
escapedTxt += txt.charAt(i); | ||
} | ||
} | ||
return escapedTxt; | ||
} | ||
function alignDigits(buffer, digits, opts, force) { | ||
if (buffer.length > 0 && digits > 0 && (!opts.digitsOptional || force)) { | ||
var radixPosition = buffer.indexOf(opts.radixPoint), negationBack = false; | ||
if (opts.negationSymbol.back === buffer[buffer.length - 1]) { | ||
negationBack = true; | ||
buffer.length--; | ||
} | ||
if (buffer.length > 0 && digits > 0 && (!opts.digitsOptional || force)) { | ||
var radixPosition = buffer.indexOf(opts.radixPoint), | ||
negationBack = false; | ||
if (opts.negationSymbol.back === buffer[buffer.length - 1]) { | ||
negationBack = true; | ||
buffer.length--; | ||
} | ||
if (radixPosition === -1) { | ||
buffer.push(opts.radixPoint); | ||
radixPosition = buffer.length - 1; | ||
} | ||
for (var i = 1; i <= digits; i++) { | ||
if (!isFinite(buffer[radixPosition + i])) { | ||
buffer[radixPosition + i] = "0"; | ||
} | ||
} | ||
} | ||
if (radixPosition === -1) { | ||
buffer.push(opts.radixPoint); | ||
radixPosition = buffer.length - 1; | ||
} | ||
for (let i = 1; i <= digits; i++) { | ||
if (!isFinite(buffer[radixPosition + i])) { | ||
buffer[radixPosition + i] = "0"; | ||
} | ||
} | ||
} | ||
if (negationBack) | ||
buffer.push(opts.negationSymbol.back); | ||
return buffer; | ||
if (negationBack) buffer.push(opts.negationSymbol.back); | ||
return buffer; | ||
} | ||
function findValidator(symbol, maskset) { | ||
var posNdx = 0; | ||
if (symbol === "+") { | ||
posNdx = seekNext.call(this, maskset.validPositions.length - 1); | ||
} | ||
for (var tstNdx in maskset.tests) { | ||
tstNdx = parseInt(tstNdx); | ||
if (tstNdx >= posNdx) { | ||
for (var ndx = 0, ndxl = maskset.tests[tstNdx].length; ndx < ndxl; ndx++) { | ||
if ((maskset.validPositions[tstNdx] === undefined || symbol === "-") && maskset.tests[tstNdx][ndx].match.def === symbol) { | ||
return tstNdx + ((maskset.validPositions[tstNdx] !== undefined && symbol !== "-") ? 1 : 0); | ||
} | ||
} | ||
} | ||
} | ||
return posNdx; | ||
let posNdx = 0; | ||
if (symbol === "+") { | ||
posNdx = seekNext.call(this, maskset.validPositions.length - 1); | ||
} | ||
for (let tstNdx in maskset.tests) { | ||
tstNdx = parseInt(tstNdx); | ||
if (tstNdx >= posNdx) { | ||
for ( | ||
let ndx = 0, ndxl = maskset.tests[tstNdx].length; | ||
ndx < ndxl; | ||
ndx++ | ||
) { | ||
if ( | ||
(maskset.validPositions[tstNdx] === undefined || symbol === "-") && | ||
maskset.tests[tstNdx][ndx].match.def === symbol | ||
) { | ||
return ( | ||
tstNdx + | ||
(maskset.validPositions[tstNdx] !== undefined && symbol !== "-" | ||
? 1 | ||
: 0) | ||
); | ||
} | ||
} | ||
} | ||
} | ||
return posNdx; | ||
} | ||
function findValid(symbol, maskset) { | ||
var ret = -1; | ||
for (let ndx = 0, vpl = maskset.validPositions.length; ndx < vpl; ndx++) { | ||
let tst = maskset.validPositions[ndx]; | ||
if (tst && tst.match.def === symbol) { | ||
ret = ndx; | ||
break; | ||
} | ||
} | ||
return ret; | ||
let ret = -1; | ||
for (let ndx = 0, vpl = maskset.validPositions.length; ndx < vpl; ndx++) { | ||
const tst = maskset.validPositions[ndx]; | ||
if (tst && tst.match.def === symbol) { | ||
ret = ndx; | ||
break; | ||
} | ||
} | ||
return ret; | ||
} | ||
function parseMinMaxOptions(opts) { | ||
if (opts.parseMinMaxOptions === undefined) { | ||
// convert min and max options | ||
if (opts.min !== null) { | ||
opts.min = opts.min.toString().replace(new RegExp(escapeRegex(opts.groupSeparator), "g"), ""); | ||
if (opts.radixPoint === ",") opts.min = opts.min.replace(opts.radixPoint, "."); | ||
opts.min = isFinite(opts.min) ? parseFloat(opts.min) : NaN; | ||
if (isNaN(opts.min)) opts.min = Number.MIN_VALUE; | ||
} | ||
if (opts.max !== null) { | ||
opts.max = opts.max.toString().replace(new RegExp(escapeRegex(opts.groupSeparator), "g"), ""); | ||
if (opts.radixPoint === ",") opts.max = opts.max.replace(opts.radixPoint, "."); | ||
opts.max = isFinite(opts.max) ? parseFloat(opts.max) : NaN; | ||
if (isNaN(opts.max)) opts.max = Number.MAX_VALUE; | ||
} | ||
opts.parseMinMaxOptions = "done"; | ||
} | ||
if (opts.parseMinMaxOptions === undefined) { | ||
// convert min and max options | ||
if (opts.min !== null) { | ||
opts.min = opts.min | ||
.toString() | ||
.replace(new RegExp(escapeRegex(opts.groupSeparator), "g"), ""); | ||
if (opts.radixPoint === ",") | ||
opts.min = opts.min.replace(opts.radixPoint, "."); | ||
opts.min = isFinite(opts.min) ? parseFloat(opts.min) : NaN; | ||
if (isNaN(opts.min)) opts.min = Number.MIN_VALUE; | ||
} | ||
if (opts.max !== null) { | ||
opts.max = opts.max | ||
.toString() | ||
.replace(new RegExp(escapeRegex(opts.groupSeparator), "g"), ""); | ||
if (opts.radixPoint === ",") | ||
opts.max = opts.max.replace(opts.radixPoint, "."); | ||
opts.max = isFinite(opts.max) ? parseFloat(opts.max) : NaN; | ||
if (isNaN(opts.max)) opts.max = Number.MAX_VALUE; | ||
} | ||
opts.parseMinMaxOptions = "done"; | ||
} | ||
} | ||
function genMask(opts) { | ||
opts.repeat = 0; | ||
//treat equal separator and radixpoint | ||
if (opts.groupSeparator === opts.radixPoint && opts.digits && opts.digits !== "0") { | ||
if (opts.radixPoint === ".") { | ||
opts.groupSeparator = ","; | ||
} else if (opts.radixPoint === ",") { | ||
opts.groupSeparator = "."; | ||
} else { | ||
opts.groupSeparator = ""; | ||
} | ||
} | ||
//prevent conflict with default skipOptionalPartCharacter | ||
if (opts.groupSeparator === " ") { | ||
opts.skipOptionalPartCharacter = undefined; | ||
} | ||
opts.repeat = 0; | ||
// treat equal separator and radixpoint | ||
if ( | ||
opts.groupSeparator === opts.radixPoint && | ||
opts.digits && | ||
opts.digits !== "0" | ||
) { | ||
if (opts.radixPoint === ".") { | ||
opts.groupSeparator = ","; | ||
} else if (opts.radixPoint === ",") { | ||
opts.groupSeparator = "."; | ||
} else { | ||
opts.groupSeparator = ""; | ||
} | ||
} | ||
// prevent conflict with default skipOptionalPartCharacter | ||
if (opts.groupSeparator === " ") { | ||
opts.skipOptionalPartCharacter = undefined; | ||
} | ||
//enforce placeholder to single | ||
if (opts.placeholder.length > 1) { | ||
opts.placeholder = opts.placeholder.charAt(0); | ||
} | ||
//only allow radixfocus when placeholder = 0 | ||
if (opts.positionCaretOnClick === "radixFocus" && opts.placeholder === "") { | ||
opts.positionCaretOnClick = "lvp"; | ||
} | ||
// enforce placeholder to single | ||
if (opts.placeholder.length > 1) { | ||
opts.placeholder = opts.placeholder.charAt(0); | ||
} | ||
// only allow radixfocus when placeholder = 0 | ||
if (opts.positionCaretOnClick === "radixFocus" && opts.placeholder === "") { | ||
opts.positionCaretOnClick = "lvp"; | ||
} | ||
var decimalDef = "0", radixPointDef = opts.radixPoint; | ||
if (opts.numericInput === true && opts.__financeInput === undefined) { //finance people input style | ||
decimalDef = "1"; | ||
opts.positionCaretOnClick = opts.positionCaretOnClick === "radixFocus" ? "lvp" : opts.positionCaretOnClick; | ||
opts.digitsOptional = false; | ||
if (isNaN(opts.digits)) opts.digits = 2; | ||
opts._radixDance = false; | ||
radixPointDef = (opts.radixPoint === "," ? "?" : "!"); | ||
if (opts.radixPoint !== "" && opts.definitions[radixPointDef] === undefined) { | ||
//update separator definition | ||
opts.definitions[radixPointDef] = {}; | ||
opts.definitions[radixPointDef].validator = "[" + opts.radixPoint + "]"; | ||
opts.definitions[radixPointDef].placeholder = opts.radixPoint; | ||
opts.definitions[radixPointDef].static = true; | ||
opts.definitions[radixPointDef].generated = true; //forced marker as generated input | ||
} | ||
} else { | ||
opts.__financeInput = false; //needed to keep original selection when remasking | ||
opts.numericInput = true; | ||
} | ||
let decimalDef = "0", | ||
radixPointDef = opts.radixPoint; | ||
if (opts.numericInput === true && opts.__financeInput === undefined) { | ||
// finance people input style | ||
decimalDef = "1"; | ||
opts.positionCaretOnClick = | ||
opts.positionCaretOnClick === "radixFocus" | ||
? "lvp" | ||
: opts.positionCaretOnClick; | ||
opts.digitsOptional = false; | ||
if (isNaN(opts.digits)) opts.digits = 2; | ||
opts._radixDance = false; | ||
radixPointDef = opts.radixPoint === "," ? "?" : "!"; | ||
if ( | ||
opts.radixPoint !== "" && | ||
opts.definitions[radixPointDef] === undefined | ||
) { | ||
// update separator definition | ||
opts.definitions[radixPointDef] = {}; | ||
opts.definitions[radixPointDef].validator = "[" + opts.radixPoint + "]"; | ||
opts.definitions[radixPointDef].placeholder = opts.radixPoint; | ||
opts.definitions[radixPointDef].static = true; | ||
opts.definitions[radixPointDef].generated = true; // forced marker as generated input | ||
} | ||
} else { | ||
opts.__financeInput = false; // needed to keep original selection when remasking | ||
opts.numericInput = true; | ||
} | ||
var mask = "[+]", altMask; | ||
mask += autoEscape(opts.prefix, opts); | ||
if (opts.groupSeparator !== "") { | ||
if (opts.definitions[opts.groupSeparator] === undefined) { | ||
//update separator definition | ||
opts.definitions[opts.groupSeparator] = {}; | ||
opts.definitions[opts.groupSeparator].validator = "[" + opts.groupSeparator + "]"; | ||
opts.definitions[opts.groupSeparator].placeholder = opts.groupSeparator; | ||
opts.definitions[opts.groupSeparator].static = true; | ||
opts.definitions[opts.groupSeparator].generated = true; //forced marker as generated input | ||
} | ||
mask += opts._mask(opts); | ||
} else { | ||
mask += "9{+}"; | ||
} | ||
if (opts.digits !== undefined && opts.digits !== 0) { | ||
var dq = opts.digits.toString().split(","); | ||
if (isFinite(dq[0]) && dq[1] && isFinite(dq[1])) { | ||
mask += radixPointDef + decimalDef + "{" + opts.digits + "}"; | ||
} else if (isNaN(opts.digits) || parseInt(opts.digits) > 0) { | ||
if (opts.digitsOptional || opts.jitMasking) { | ||
altMask = mask + radixPointDef + decimalDef + "{0," + opts.digits + "}"; | ||
// mask += "[" + opts.radixPoint + "]"; | ||
opts.keepStatic = true; | ||
} else { | ||
mask += radixPointDef + decimalDef + "{" + opts.digits + "}"; | ||
} | ||
} | ||
} else { | ||
opts.inputmode = "numeric"; | ||
} | ||
mask += autoEscape(opts.suffix, opts); | ||
mask += "[-]"; | ||
let mask = "[+]", | ||
altMask; | ||
mask += autoEscape(opts.prefix, opts); | ||
if (opts.groupSeparator !== "") { | ||
if (opts.definitions[opts.groupSeparator] === undefined) { | ||
// update separator definition | ||
opts.definitions[opts.groupSeparator] = {}; | ||
opts.definitions[opts.groupSeparator].validator = | ||
"[" + opts.groupSeparator + "]"; | ||
opts.definitions[opts.groupSeparator].placeholder = opts.groupSeparator; | ||
opts.definitions[opts.groupSeparator].static = true; | ||
opts.definitions[opts.groupSeparator].generated = true; // forced marker as generated input | ||
} | ||
mask += opts._mask(opts); | ||
} else { | ||
mask += "9{+}"; | ||
} | ||
if (opts.digits !== undefined && opts.digits !== 0) { | ||
const dq = opts.digits.toString().split(","); | ||
if (isFinite(dq[0]) && dq[1] && isFinite(dq[1])) { | ||
mask += radixPointDef + decimalDef + "{" + opts.digits + "}"; | ||
} else if (isNaN(opts.digits) || parseInt(opts.digits) > 0) { | ||
if (opts.digitsOptional || opts.jitMasking) { | ||
altMask = mask + radixPointDef + decimalDef + "{0," + opts.digits + "}"; | ||
// mask += "[" + opts.radixPoint + "]"; | ||
opts.keepStatic = true; | ||
} else { | ||
mask += radixPointDef + decimalDef + "{" + opts.digits + "}"; | ||
} | ||
} | ||
} else { | ||
opts.inputmode = "numeric"; | ||
} | ||
mask += autoEscape(opts.suffix, opts); | ||
mask += "[-]"; | ||
if (altMask) { | ||
mask = [(altMask + autoEscape(opts.suffix, opts) + "[-]"), mask]; | ||
} | ||
if (altMask) { | ||
mask = [altMask + autoEscape(opts.suffix, opts) + "[-]", mask]; | ||
} | ||
opts.greedy = false; //enforce greedy false | ||
opts.greedy = false; // enforce greedy false | ||
parseMinMaxOptions(opts); | ||
if (opts.radixPoint !== "" && opts.substituteRadixPoint) | ||
opts.substitutes[opts.radixPoint == "." ? "," : "."] = opts.radixPoint; | ||
// console.log(mask); | ||
return mask; | ||
parseMinMaxOptions(opts); | ||
if (opts.radixPoint !== "" && opts.substituteRadixPoint) | ||
opts.substitutes[opts.radixPoint == "." ? "," : "."] = opts.radixPoint; | ||
// console.log(mask); | ||
return mask; | ||
} | ||
function hanndleRadixDance(pos, c, radixPos, maskset, opts) { | ||
if (opts._radixDance && opts.numericInput && c !== opts.negationSymbol.back) { | ||
if (pos <= radixPos && (radixPos > 0 || c == opts.radixPoint) && (maskset.validPositions[pos - 1] === undefined || maskset.validPositions[pos - 1].input !== opts.negationSymbol.back)) { | ||
pos -= 1; | ||
} | ||
} | ||
return pos; | ||
if (opts._radixDance && opts.numericInput && c !== opts.negationSymbol.back) { | ||
if ( | ||
pos <= radixPos && | ||
(radixPos > 0 || c == opts.radixPoint) && | ||
(maskset.validPositions[pos - 1] === undefined || | ||
maskset.validPositions[pos - 1].input !== opts.negationSymbol.back) | ||
) { | ||
pos -= 1; | ||
} | ||
} | ||
return pos; | ||
} | ||
function decimalValidator(chrs, maskset, pos, strict, opts) { | ||
var radixPos = maskset.buffer ? maskset.buffer.indexOf(opts.radixPoint) : -1, | ||
result = (radixPos !== -1 || (strict && opts.jitMasking)) && new RegExp(opts.definitions["9"].validator).test(chrs); | ||
if (opts._radixDance && radixPos !== -1 && result && maskset.validPositions[radixPos] == undefined) { | ||
return { | ||
insert: { | ||
pos: radixPos === pos ? radixPos + 1 : radixPos, | ||
c: opts.radixPoint | ||
}, | ||
pos: pos | ||
}; | ||
} | ||
const radixPos = maskset.buffer | ||
? maskset.buffer.indexOf(opts.radixPoint) | ||
: -1, | ||
result = | ||
(radixPos !== -1 || (strict && opts.jitMasking)) && | ||
new RegExp(opts.definitions["9"].validator).test(chrs); | ||
if ( | ||
!strict && | ||
opts._radixDance && | ||
radixPos !== -1 && | ||
result && | ||
maskset.validPositions[radixPos] == undefined | ||
) { | ||
return { | ||
insert: { | ||
pos: radixPos === pos ? radixPos + 1 : radixPos, | ||
c: opts.radixPoint | ||
}, | ||
pos | ||
}; | ||
} | ||
return result; | ||
return result; | ||
} | ||
function checkForLeadingZeroes(buffer, opts) { | ||
//check leading zeros | ||
var numberMatches = new RegExp("(^" + (opts.negationSymbol.front !== "" ? escapeRegex(opts.negationSymbol.front) + "?" : "") + escapeRegex(opts.prefix) + ")(.*)(" + escapeRegex(opts.suffix) + (opts.negationSymbol.back != "" ? escapeRegex(opts.negationSymbol.back) + "?" : "") + "$)").exec(buffer.slice().reverse().join("")), | ||
number = numberMatches ? numberMatches[2] : "", leadingzeroes = false; | ||
if (number) { | ||
number = number.split(opts.radixPoint.charAt(0))[0]; | ||
leadingzeroes = new RegExp("^[0" + opts.groupSeparator + "]*").exec(number); | ||
} | ||
return leadingzeroes && (leadingzeroes[0].length > 1 || leadingzeroes[0].length > 0 && leadingzeroes[0].length < number.length) ? leadingzeroes : false; | ||
// check leading zeros | ||
let numberMatches = new RegExp( | ||
"(^" + | ||
(opts.negationSymbol.front !== "" | ||
? escapeRegex(opts.negationSymbol.front) + "?" | ||
: "") + | ||
escapeRegex(opts.prefix) + | ||
")(.*)(" + | ||
escapeRegex(opts.suffix) + | ||
(opts.negationSymbol.back != "" | ||
? escapeRegex(opts.negationSymbol.back) + "?" | ||
: "") + | ||
"$)" | ||
).exec(buffer.slice().reverse().join("")), | ||
number = numberMatches ? numberMatches[2] : "", | ||
leadingzeroes = false; | ||
if (number) { | ||
number = number.split(opts.radixPoint.charAt(0))[0]; | ||
leadingzeroes = new RegExp("^[0" + opts.groupSeparator + "]*").exec(number); | ||
} | ||
return leadingzeroes && | ||
(leadingzeroes[0].length > 1 || | ||
(leadingzeroes[0].length > 0 && leadingzeroes[0].length < number.length)) | ||
? leadingzeroes | ||
: false; | ||
} | ||
//number aliases | ||
// number aliases | ||
Inputmask.extendAliases({ | ||
"numeric": { | ||
mask: genMask, | ||
_mask: function (opts) { | ||
return "(" + opts.groupSeparator + "999){+|1}"; | ||
}, | ||
digits: "*", //number of fractionalDigits | ||
digitsOptional: true, | ||
enforceDigitsOnBlur: false, | ||
radixPoint: ".", | ||
positionCaretOnClick: "radixFocus", | ||
_radixDance: true, | ||
groupSeparator: "", | ||
allowMinus: true, | ||
negationSymbol: { | ||
front: "-", //"(" | ||
back: "" //")" | ||
}, | ||
prefix: "", | ||
suffix: "", | ||
min: null, //minimum value | ||
max: null, //maximum value | ||
SetMaxOnOverflow: false, | ||
step: 1, | ||
inputType: "text", //number ~ specify that values which are set are in textform (radix point is same as in the options) or in numberform (radixpoint = .) | ||
unmaskAsNumber: false, | ||
roundingFN: Math.round, //Math.floor , fn(x) | ||
inputmode: "decimal", | ||
shortcuts: {k: "1000", m: "1000000"}, | ||
//global options | ||
placeholder: "0", | ||
greedy: false, | ||
rightAlign: true, | ||
insertMode: true, | ||
autoUnmask: false, | ||
skipOptionalPartCharacter: "", | ||
usePrototypeDefinitions: false, | ||
stripLeadingZeroes: true, | ||
substituteRadixPoint: true, | ||
definitions: { | ||
"0": { | ||
validator: decimalValidator | ||
}, | ||
"1": { | ||
validator: decimalValidator, | ||
definitionSymbol: "9" | ||
}, | ||
"9": { //\uFF11-\uFF19 #1606 | ||
validator: "[0-9\uFF10-\uFF19\u0660-\u0669\u06F0-\u06F9]", | ||
definitionSymbol: "*" | ||
}, | ||
"+": { | ||
validator: function (chrs, maskset, pos, strict, opts) { | ||
return (opts.allowMinus && (chrs === "-" || chrs === opts.negationSymbol.front)); | ||
numeric: { | ||
mask: genMask, | ||
_mask: function (opts) { | ||
return "(" + opts.groupSeparator + "999){+|1}"; | ||
}, | ||
digits: "*", // number of fractionalDigits | ||
digitsOptional: true, | ||
enforceDigitsOnBlur: false, | ||
radixPoint: ".", | ||
positionCaretOnClick: "radixFocus", | ||
_radixDance: true, | ||
groupSeparator: "", | ||
allowMinus: true, | ||
negationSymbol: { | ||
front: "-", // "(" | ||
back: "" // ")" | ||
}, | ||
prefix: "", | ||
suffix: "", | ||
min: null, // minimum value | ||
max: null, // maximum value | ||
SetMaxOnOverflow: false, | ||
step: 1, | ||
inputType: "text", // number ~ specify that values which are set are in textform (radix point is same as in the options) or in numberform (radixpoint = .) | ||
unmaskAsNumber: false, | ||
roundingFN: Math.round, // Math.floor , fn(x) | ||
inputmode: "decimal", | ||
shortcuts: { k: "1000", m: "1000000" }, | ||
// global options | ||
placeholder: "0", | ||
greedy: false, | ||
rightAlign: true, | ||
insertMode: true, | ||
autoUnmask: false, | ||
skipOptionalPartCharacter: "", | ||
usePrototypeDefinitions: false, | ||
stripLeadingZeroes: true, | ||
substituteRadixPoint: true, | ||
definitions: { | ||
0: { | ||
validator: decimalValidator | ||
}, | ||
1: { | ||
validator: decimalValidator, | ||
definitionSymbol: "9" | ||
}, | ||
9: { | ||
// \uFF11-\uFF19 #1606 | ||
validator: "[0-9\uFF10-\uFF19\u0660-\u0669\u06F0-\u06F9]", | ||
definitionSymbol: "*" | ||
}, | ||
"+": { | ||
validator: function (chrs, maskset, pos, strict, opts) { | ||
return ( | ||
opts.allowMinus && | ||
(chrs === "-" || chrs === opts.negationSymbol.front) | ||
); | ||
} | ||
}, | ||
"-": { | ||
validator: function (chrs, maskset, pos, strict, opts) { | ||
return opts.allowMinus && chrs === opts.negationSymbol.back; | ||
} | ||
} | ||
}, | ||
preValidation: function ( | ||
buffer, | ||
pos, | ||
c, | ||
isSelection, | ||
opts, | ||
maskset, | ||
caretPos, | ||
strict | ||
) { | ||
const inputmask = this; | ||
} | ||
}, | ||
"-": { | ||
validator: function (chrs, maskset, pos, strict, opts) { | ||
return (opts.allowMinus && chrs === opts.negationSymbol.back); | ||
} | ||
} | ||
}, | ||
preValidation: function (buffer, pos, c, isSelection, opts, maskset, caretPos, strict) { | ||
const inputmask = this; | ||
if (opts.__financeInput !== false && c === opts.radixPoint) return false; | ||
const radixPos = buffer.indexOf(opts.radixPoint), | ||
initPos = pos; | ||
pos = hanndleRadixDance(pos, c, radixPos, maskset, opts); | ||
if (c === "-" || c === opts.negationSymbol.front) { | ||
if (opts.allowMinus !== true) return false; | ||
let isNegative = false, | ||
front = findValid("+", maskset), | ||
back = findValid("-", maskset); | ||
if (front !== -1) { | ||
isNegative = [front, back]; | ||
} | ||
if (opts.__financeInput !== false && c === opts.radixPoint) return false; | ||
var radixPos = buffer.indexOf(opts.radixPoint), initPos = pos; | ||
pos = hanndleRadixDance(pos, c, radixPos, maskset, opts); | ||
if (c === "-" || c === opts.negationSymbol.front) { | ||
if (opts.allowMinus !== true) return false; | ||
var isNegative = false, | ||
front = findValid("+", maskset), back = findValid("-", maskset); | ||
if (front !== -1) { | ||
isNegative = [front, back]; | ||
} | ||
return isNegative !== false | ||
? { | ||
remove: isNegative, | ||
caret: initPos - opts.negationSymbol.back.length | ||
} | ||
: { | ||
insert: [ | ||
{ | ||
pos: findValidator.call(inputmask, "+", maskset), | ||
c: opts.negationSymbol.front, | ||
fromIsValid: true | ||
}, | ||
{ | ||
pos: findValidator.call(inputmask, "-", maskset), | ||
c: opts.negationSymbol.back, | ||
fromIsValid: undefined | ||
} | ||
], | ||
caret: initPos + opts.negationSymbol.back.length | ||
}; | ||
} | ||
return isNegative !== false ? { | ||
remove: isNegative, | ||
caret: initPos - opts.negationSymbol.back.length | ||
} : { | ||
insert: [ | ||
{ | ||
pos: findValidator.call(inputmask, "+", maskset), | ||
c: opts.negationSymbol.front, | ||
fromIsValid: true | ||
}, | ||
{ | ||
pos: findValidator.call(inputmask, "-", maskset), | ||
c: opts.negationSymbol.back, | ||
fromIsValid: undefined | ||
}], | ||
caret: initPos + opts.negationSymbol.back.length | ||
}; | ||
} | ||
if (c === opts.groupSeparator) { | ||
return { caret: initPos }; | ||
} | ||
if (c === opts.groupSeparator) { | ||
return {caret: initPos}; | ||
} | ||
if (strict) return true; | ||
if ( | ||
radixPos !== -1 && | ||
opts._radixDance === true && | ||
isSelection === false && | ||
c === opts.radixPoint && | ||
opts.digits !== undefined && | ||
(isNaN(opts.digits) || parseInt(opts.digits) > 0) && | ||
radixPos !== pos | ||
) { | ||
const radixValidatorPos = findValidator.call( | ||
inputmask, | ||
opts.radixPoint, | ||
maskset | ||
); | ||
if (maskset.validPositions[radixValidatorPos]) { | ||
maskset.validPositions[radixValidatorPos].generatedInput = | ||
maskset.validPositions[radixValidatorPos].generated || false; | ||
} | ||
return { | ||
caret: | ||
opts._radixDance && pos === radixPos - 1 ? radixPos + 1 : radixPos | ||
}; | ||
} | ||
if (opts.__financeInput === false) { | ||
if (isSelection) { | ||
if (opts.digitsOptional) { | ||
return { rewritePosition: caretPos.end }; | ||
} else if (!opts.digitsOptional) { | ||
if (caretPos.begin > radixPos && caretPos.end <= radixPos) { | ||
if (c === opts.radixPoint) { | ||
return { | ||
insert: { pos: radixPos + 1, c: "0", fromIsValid: true }, | ||
rewritePosition: radixPos | ||
}; | ||
} else { | ||
return { rewritePosition: radixPos + 1 }; | ||
} | ||
} else if (caretPos.begin < radixPos) { | ||
return { rewritePosition: caretPos.begin - 1 }; | ||
} | ||
} | ||
} else if ( | ||
!opts.showMaskOnHover && | ||
!opts.showMaskOnFocus && | ||
!opts.digitsOptional && | ||
opts.digits > 0 && | ||
this.__valueGet.call(this.el) === "" | ||
) { | ||
return { rewritePosition: radixPos }; | ||
} | ||
} | ||
return { rewritePosition: pos }; | ||
}, | ||
postValidation: function ( | ||
buffer, | ||
pos, | ||
c, | ||
currentResult, | ||
opts, | ||
maskset, | ||
strict | ||
) { | ||
if (currentResult === false) return currentResult; | ||
if (strict) return true; | ||
if (opts.min !== null || opts.max !== null) { | ||
const unmasked = opts.onUnMask( | ||
buffer.slice().reverse().join(""), | ||
undefined, | ||
$.extend({}, opts, { | ||
unmaskAsNumber: true | ||
}) | ||
); | ||
if ( | ||
opts.min !== null && | ||
unmasked < opts.min && | ||
(unmasked.toString().length > opts.min.toString().length || | ||
unmasked < 0) | ||
) { | ||
return false; | ||
// return { | ||
// refreshFromBuffer: true, | ||
// buffer: alignDigits(opts.min.toString().replace(".", opts.radixPoint).split(""), opts.digits, opts).reverse() | ||
// }; | ||
} | ||
if (strict) return true; | ||
if (radixPos !== -1 && (opts._radixDance === true && isSelection === false && c === opts.radixPoint && (opts.digits !== undefined && (isNaN(opts.digits) || parseInt(opts.digits) > 0)) && radixPos !== pos)) { | ||
var radixValidatorPos = findValidator.call(inputmask, opts.radixPoint, maskset);; | ||
if(maskset.validPositions[radixValidatorPos]) { | ||
maskset.validPositions[radixValidatorPos].generatedInput = maskset.validPositions[radixValidatorPos].generated || false; | ||
} | ||
return { | ||
"caret": opts._radixDance && pos === radixPos - 1 ? radixPos + 1 : radixPos | ||
}; | ||
} | ||
if (opts.__financeInput === false) { | ||
if (isSelection) { | ||
if (opts.digitsOptional) { | ||
return {rewritePosition: caretPos.end}; | ||
} else if (!opts.digitsOptional) { | ||
if (caretPos.begin > radixPos && caretPos.end <= radixPos) { | ||
if (c === opts.radixPoint) { | ||
return { | ||
insert: {pos: radixPos + 1, c: "0", fromIsValid: true}, | ||
rewritePosition: radixPos | ||
}; | ||
} else { | ||
return {rewritePosition: radixPos + 1}; | ||
} | ||
} else if (caretPos.begin < radixPos) { | ||
return {rewritePosition: caretPos.begin - 1}; | ||
} | ||
} | ||
} else if (!opts.showMaskOnHover && !opts.showMaskOnFocus && !opts.digitsOptional && opts.digits > 0 && this.__valueGet.call(this.el) === "") { | ||
return {rewritePosition: radixPos}; | ||
} | ||
} | ||
return {rewritePosition: pos}; | ||
}, | ||
postValidation: function (buffer, pos, c, currentResult, opts, maskset, strict) { | ||
if (currentResult === false) return currentResult; | ||
if (strict) return true; | ||
if (opts.min !== null || opts.max !== null) { | ||
var unmasked = opts.onUnMask(buffer.slice().reverse().join(""), undefined, $.extend({}, opts, { | ||
unmaskAsNumber: true | ||
})); | ||
if (opts.min !== null && unmasked < opts.min && (unmasked.toString().length > opts.min.toString().length || unmasked < 0)) { | ||
return false; | ||
// return { | ||
// refreshFromBuffer: true, | ||
// buffer: alignDigits(opts.min.toString().replace(".", opts.radixPoint).split(""), opts.digits, opts).reverse() | ||
// }; | ||
} | ||
if (opts.max !== null && unmasked > opts.max) { | ||
return opts.SetMaxOnOverflow | ||
? { | ||
refreshFromBuffer: true, | ||
buffer: alignDigits( | ||
opts.max.toString().replace(".", opts.radixPoint).split(""), | ||
opts.digits, | ||
opts | ||
).reverse() | ||
} | ||
: false; | ||
} | ||
} | ||
if (opts.max !== null && unmasked > opts.max) { | ||
return opts.SetMaxOnOverflow ? { | ||
refreshFromBuffer: true, | ||
buffer: alignDigits(opts.max.toString().replace(".", opts.radixPoint).split(""), opts.digits, opts).reverse() | ||
} : false; | ||
} | ||
} | ||
return currentResult; | ||
}, | ||
onUnMask: function (maskedValue, unmaskedValue, opts) { | ||
if (unmaskedValue === "" && opts.nullable === true) { | ||
return unmaskedValue; | ||
} | ||
let processValue = maskedValue.replace(opts.prefix, ""); | ||
processValue = processValue.replace(opts.suffix, ""); | ||
processValue = processValue.replace( | ||
new RegExp(escapeRegex(opts.groupSeparator), "g"), | ||
"" | ||
); | ||
if (opts.placeholder.charAt(0) !== "") { | ||
processValue = processValue.replace( | ||
new RegExp(opts.placeholder.charAt(0), "g"), | ||
"0" | ||
); | ||
} | ||
if (opts.unmaskAsNumber) { | ||
if ( | ||
opts.radixPoint !== "" && | ||
processValue.indexOf(opts.radixPoint) !== -1 | ||
) | ||
processValue = processValue.replace( | ||
escapeRegex.call(this, opts.radixPoint), | ||
"." | ||
); | ||
processValue = processValue.replace( | ||
new RegExp("^" + escapeRegex(opts.negationSymbol.front)), | ||
"-" | ||
); | ||
processValue = processValue.replace( | ||
new RegExp(escapeRegex(opts.negationSymbol.back) + "$"), | ||
"" | ||
); | ||
return Number(processValue); | ||
} | ||
return processValue; | ||
}, | ||
isComplete: function (buffer, opts) { | ||
let maskedValue = ( | ||
opts.numericInput ? buffer.slice().reverse() : buffer | ||
).join(""); | ||
maskedValue = maskedValue.replace( | ||
new RegExp("^" + escapeRegex(opts.negationSymbol.front)), | ||
"-" | ||
); | ||
maskedValue = maskedValue.replace( | ||
new RegExp(escapeRegex(opts.negationSymbol.back) + "$"), | ||
"" | ||
); | ||
maskedValue = maskedValue.replace(opts.prefix, ""); | ||
maskedValue = maskedValue.replace(opts.suffix, ""); | ||
maskedValue = maskedValue.replace( | ||
new RegExp(escapeRegex(opts.groupSeparator) + "([0-9]{3})", "g"), | ||
"$1" | ||
); | ||
if (opts.radixPoint === ",") | ||
maskedValue = maskedValue.replace(escapeRegex(opts.radixPoint), "."); | ||
return isFinite(maskedValue); | ||
}, | ||
onBeforeMask: function (initialValue, opts) { | ||
initialValue = initialValue ?? ""; | ||
const radixPoint = opts.radixPoint || ","; | ||
if (isFinite(opts.digits)) opts.digits = parseInt(opts.digits); | ||
return currentResult; | ||
}, | ||
onUnMask: function (maskedValue, unmaskedValue, opts) { | ||
if (unmaskedValue === "" && opts.nullable === true) { | ||
return unmaskedValue; | ||
} | ||
var processValue = maskedValue.replace(opts.prefix, ""); | ||
processValue = processValue.replace(opts.suffix, ""); | ||
processValue = processValue.replace(new RegExp(escapeRegex(opts.groupSeparator), "g"), ""); | ||
if (opts.placeholder.charAt(0) !== "") { | ||
processValue = processValue.replace(new RegExp(opts.placeholder.charAt(0), "g"), "0"); | ||
} | ||
if (opts.unmaskAsNumber) { | ||
if (opts.radixPoint !== "" && processValue.indexOf(opts.radixPoint) !== -1) processValue = processValue.replace(escapeRegex.call(this, opts.radixPoint), "."); | ||
processValue = processValue.replace(new RegExp("^" + escapeRegex(opts.negationSymbol.front)), "-"); | ||
processValue = processValue.replace(new RegExp(escapeRegex(opts.negationSymbol.back) + "$"), ""); | ||
return Number(processValue); | ||
} | ||
return processValue; | ||
} | ||
, | ||
isComplete: function (buffer, opts) { | ||
var maskedValue = (opts.numericInput ? buffer.slice().reverse() : buffer).join(""); | ||
maskedValue = maskedValue.replace(new RegExp("^" + escapeRegex(opts.negationSymbol.front)), "-"); | ||
maskedValue = maskedValue.replace(new RegExp(escapeRegex(opts.negationSymbol.back) + "$"), ""); | ||
maskedValue = maskedValue.replace(opts.prefix, ""); | ||
maskedValue = maskedValue.replace(opts.suffix, ""); | ||
maskedValue = maskedValue.replace(new RegExp(escapeRegex(opts.groupSeparator) + "([0-9]{3})", "g"), "$1"); | ||
if (opts.radixPoint === ",") maskedValue = maskedValue.replace(escapeRegex(opts.radixPoint), "."); | ||
return isFinite(maskedValue); | ||
}, | ||
onBeforeMask: function (initialValue, opts) { | ||
var radixPoint = opts.radixPoint || ","; | ||
if (isFinite(opts.digits)) opts.digits = parseInt(opts.digits); | ||
if ( | ||
(typeof initialValue === "number" || opts.inputType === "number") && | ||
radixPoint !== "" | ||
) { | ||
initialValue = initialValue.toString().replace(".", radixPoint); | ||
} | ||
const isNegative = | ||
initialValue.charAt(0) === "-" || | ||
initialValue.charAt(0) === opts.negationSymbol.front, | ||
valueParts = initialValue.split(radixPoint), | ||
integerPart = valueParts[0].replace(/[^\-0-9]/g, ""), | ||
decimalPart = | ||
valueParts.length > 1 ? valueParts[1].replace(/[^0-9]/g, "") : "", | ||
forceDigits = valueParts.length > 1; | ||
if ((typeof initialValue == "number" || opts.inputType === "number") && radixPoint !== "") { | ||
initialValue = initialValue.toString().replace(".", radixPoint); | ||
} | ||
var isNagtive = initialValue.charAt(0) === "-" || initialValue.charAt(0) === opts.negationSymbol.front; | ||
var valueParts = initialValue.split(radixPoint), | ||
integerPart = valueParts[0].replace(/[^\-0-9]/g, ""), | ||
decimalPart = valueParts.length > 1 ? valueParts[1].replace(/[^0-9]/g, "") : "", | ||
forceDigits = valueParts.length > 1; | ||
initialValue = | ||
integerPart + | ||
(decimalPart !== "" ? radixPoint + decimalPart : decimalPart); | ||
initialValue = integerPart + (decimalPart !== "" ? radixPoint + decimalPart : decimalPart); | ||
let digits = 0; | ||
if (radixPoint !== "") { | ||
digits = !opts.digitsOptional | ||
? opts.digits | ||
: opts.digits < decimalPart.length | ||
? opts.digits | ||
: decimalPart.length; | ||
if (decimalPart !== "" || !opts.digitsOptional) { | ||
const digitsFactor = Math.pow(10, digits || 1); | ||
var digits = 0; | ||
if (radixPoint !== "") { | ||
digits = !opts.digitsOptional ? opts.digits : (opts.digits < decimalPart.length ? opts.digits : decimalPart.length); | ||
if (decimalPart !== "" || !opts.digitsOptional) { | ||
var digitsFactor = Math.pow(10, digits || 1); | ||
// make the initialValue a valid javascript number for the parsefloat | ||
initialValue = initialValue.replace(escapeRegex(radixPoint), "."); | ||
if (!isNaN(parseFloat(initialValue))) { | ||
initialValue = ( | ||
opts.roundingFN(parseFloat(initialValue) * digitsFactor) / | ||
digitsFactor | ||
).toFixed(digits); | ||
} | ||
initialValue = initialValue.toString().replace(".", radixPoint); | ||
} | ||
} | ||
// this needs to be in a separate part and not directly in decimalPart to allow rounding | ||
if (opts.digits === 0 && initialValue.indexOf(radixPoint) !== -1) { | ||
initialValue = initialValue.substring( | ||
0, | ||
initialValue.indexOf(radixPoint) | ||
); | ||
} | ||
//make the initialValue a valid javascript number for the parsefloat | ||
initialValue = initialValue.replace(escapeRegex(radixPoint), "."); | ||
if (!isNaN(parseFloat(initialValue))) { | ||
initialValue = (opts.roundingFN(parseFloat(initialValue) * digitsFactor) / digitsFactor).toFixed(digits); | ||
} | ||
initialValue = initialValue.toString().replace(".", radixPoint); | ||
} | ||
} | ||
//this needs to be in a separate part and not directly in decimalPart to allow rounding | ||
if (opts.digits === 0 && initialValue.indexOf(radixPoint) !== -1) { | ||
initialValue = initialValue.substring(0, initialValue.indexOf(radixPoint)); | ||
} | ||
if (opts.min !== null || opts.max !== null) { | ||
const numberValue = initialValue.toString().replace(radixPoint, "."); | ||
if (opts.min !== null && numberValue < opts.min) { | ||
initialValue = opts.min.toString().replace(".", radixPoint); | ||
} else if (opts.max !== null && numberValue > opts.max) { | ||
initialValue = opts.max.toString().replace(".", radixPoint); | ||
} | ||
} | ||
if (opts.min !== null || opts.max !== null) { | ||
var numberValue = initialValue.toString().replace(radixPoint, "."); | ||
if (opts.min !== null && numberValue < opts.min) { | ||
initialValue = opts.min.toString().replace(".", radixPoint); | ||
} else if (opts.max !== null && numberValue > opts.max) { | ||
initialValue = opts.max.toString().replace(".", radixPoint); | ||
} | ||
} | ||
if (isNegative && initialValue.charAt(0) !== "-") { | ||
initialValue = "-" + initialValue; | ||
} | ||
return alignDigits( | ||
initialValue.toString().split(""), | ||
digits, | ||
opts, | ||
forceDigits | ||
).join(""); | ||
}, | ||
onBeforeWrite: function (e, buffer, caretPos, opts) { | ||
function stripBuffer(buffer, stripRadix) { | ||
if (opts.__financeInput !== false || stripRadix) { | ||
var position = buffer.indexOf(opts.radixPoint); | ||
if (position !== -1) { | ||
buffer.splice(position, 1); | ||
} | ||
} | ||
if (opts.groupSeparator !== "") { | ||
while ((position = buffer.indexOf(opts.groupSeparator)) !== -1) { | ||
buffer.splice(position, 1); | ||
} | ||
} | ||
if (isNagtive && initialValue.charAt(0) !== "-") { | ||
initialValue = "-" + initialValue; | ||
} | ||
return alignDigits(initialValue.toString().split(""), digits, opts, forceDigits).join(""); | ||
} | ||
, | ||
onBeforeWrite: function (e, buffer, caretPos, opts) { | ||
function stripBuffer(buffer, stripRadix) { | ||
if (opts.__financeInput !== false || stripRadix) { | ||
var position = buffer.indexOf(opts.radixPoint); | ||
if (position !== -1) { | ||
buffer.splice(position, 1); | ||
} | ||
} | ||
if (opts.groupSeparator !== "") { | ||
while ((position = buffer.indexOf(opts.groupSeparator)) !== -1) { | ||
buffer.splice(position, 1); | ||
} | ||
} | ||
return buffer; | ||
} | ||
return buffer; | ||
} | ||
let result, leadingzeroes; | ||
if ( | ||
opts.stripLeadingZeroes && | ||
(leadingzeroes = checkForLeadingZeroes(buffer, opts)) | ||
) { | ||
const caretNdx = | ||
buffer | ||
.join("") | ||
.lastIndexOf(leadingzeroes[0].split("").reverse().join("")) - | ||
(leadingzeroes[0] == leadingzeroes.input ? 0 : 1), | ||
offset = leadingzeroes[0] == leadingzeroes.input ? 1 : 0; | ||
for (let i = leadingzeroes[0].length - offset; i > 0; i--) { | ||
this.maskset.validPositions.splice(caretNdx + i, 1); | ||
delete buffer[caretNdx + i]; | ||
} | ||
} | ||
let result, leadingzeroes; | ||
if (opts.stripLeadingZeroes && (leadingzeroes = checkForLeadingZeroes(buffer, opts))) { | ||
const caretNdx = buffer.join("").lastIndexOf(leadingzeroes[0].split("").reverse().join("")) - (leadingzeroes[0] == leadingzeroes.input ? 0 : 1), | ||
offset = (leadingzeroes[0] == leadingzeroes.input ? 1 : 0); | ||
for (let i = leadingzeroes[0].length - offset; i > 0; i--) { | ||
this.maskset.validPositions.splice(caretNdx + i,1); | ||
delete buffer[caretNdx + i]; | ||
} | ||
} | ||
if (e) { | ||
switch (e.type) { | ||
case "blur": | ||
case "checkval": | ||
if (opts.min !== null) { | ||
const unmasked = opts.onUnMask( | ||
buffer.slice().reverse().join(""), | ||
undefined, | ||
$.extend({}, opts, { | ||
unmaskAsNumber: true | ||
}) | ||
); | ||
if (opts.min !== null && unmasked < opts.min) { | ||
return { | ||
refreshFromBuffer: true, | ||
buffer: alignDigits( | ||
opts.min.toString().replace(".", opts.radixPoint).split(""), | ||
opts.digits, | ||
opts | ||
).reverse() | ||
}; | ||
} | ||
} | ||
if (buffer[buffer.length - 1] === opts.negationSymbol.front) { | ||
// strip negation symbol on blur when value is 0 | ||
const nmbrMtchs = new RegExp( | ||
"(^" + | ||
(opts.negationSymbol.front != "" | ||
? escapeRegex(opts.negationSymbol.front) + "?" | ||
: "") + | ||
escapeRegex(opts.prefix) + | ||
")(.*)(" + | ||
escapeRegex(opts.suffix) + | ||
(opts.negationSymbol.back != "" | ||
? escapeRegex(opts.negationSymbol.back) + "?" | ||
: "") + | ||
"$)" | ||
).exec(stripBuffer(buffer.slice(), true).reverse().join("")), | ||
number = nmbrMtchs ? nmbrMtchs[2] : ""; | ||
if (number == 0) { | ||
result = { refreshFromBuffer: true, buffer: [0] }; | ||
} | ||
} else if (opts.radixPoint !== "") { | ||
// strip radixpoint on blur when it is the latest char | ||
const radixNDX = buffer.indexOf(opts.radixPoint); | ||
if (radixNDX === opts.suffix.length) { | ||
if (result && result.buffer) { | ||
result.buffer.splice(0, 1 + opts.suffix.length); | ||
} else { | ||
buffer.splice(0, 1 + opts.suffix.length); | ||
result = { | ||
refreshFromBuffer: true, | ||
buffer: stripBuffer(buffer) | ||
}; | ||
} | ||
} | ||
} | ||
if (e) { | ||
switch (e.type) { | ||
case "blur": | ||
case "checkval": | ||
if (opts.min !== null) { | ||
var unmasked = opts.onUnMask(buffer.slice().reverse().join(""), undefined, $.extend({}, opts, { | ||
unmaskAsNumber: true | ||
})); | ||
if (opts.min !== null && unmasked < opts.min) { | ||
return { | ||
refreshFromBuffer: true, | ||
buffer: alignDigits(opts.min.toString().replace(".", opts.radixPoint).split(""), opts.digits, opts).reverse() | ||
}; | ||
} | ||
} | ||
if (buffer[buffer.length - 1] === opts.negationSymbol.front) { //strip negation symbol on blur when value is 0 | ||
var nmbrMtchs = new RegExp("(^" + (opts.negationSymbol.front != "" ? escapeRegex(opts.negationSymbol.front) + "?" : "") + escapeRegex(opts.prefix) + ")(.*)(" + escapeRegex(opts.suffix) + (opts.negationSymbol.back != "" ? escapeRegex(opts.negationSymbol.back) + "?" : "") + "$)").exec(stripBuffer(buffer.slice(), true).reverse().join("")), | ||
number = nmbrMtchs ? nmbrMtchs[2] : ""; | ||
if (number == 0) { | ||
result = {refreshFromBuffer: true, buffer: [0]}; | ||
} | ||
} else if (opts.radixPoint !== "") { //strip radixpoint on blur when it is the latest char | ||
var radixNDX = buffer.indexOf(opts.radixPoint); | ||
if (radixNDX === opts.suffix.length) { | ||
if (result && result.buffer) { | ||
result.buffer.splice(0, 1 + opts.suffix.length); | ||
} else { | ||
buffer.splice(0, 1 + opts.suffix.length); | ||
result = | ||
{refreshFromBuffer: true, buffer: stripBuffer(buffer)}; | ||
} | ||
} | ||
} | ||
if (opts.enforceDigitsOnBlur) { | ||
result = result || {}; | ||
const bffr = | ||
(result && result.buffer) || buffer.slice().reverse(); | ||
result.refreshFromBuffer = true; | ||
result.buffer = alignDigits( | ||
bffr, | ||
opts.digits, | ||
opts, | ||
true | ||
).reverse(); | ||
} | ||
} | ||
} | ||
if (opts.enforceDigitsOnBlur) { | ||
result = result || {}; | ||
var bffr = (result && result.buffer) || buffer.slice().reverse(); | ||
result.refreshFromBuffer = true; | ||
result.buffer = alignDigits(bffr, opts.digits, opts, true).reverse(); | ||
} | ||
} | ||
} | ||
return result; | ||
}, | ||
onKeyDown: function (e, buffer, caretPos, opts) { | ||
var $input = $(this), bffr; | ||
if (e.location != 3) { | ||
var pattern, c = e.key; | ||
if ((pattern = (opts.shortcuts && opts.shortcuts[c]))) { | ||
if (pattern.length > 1) { | ||
this.inputmask.__valueSet.call(this, parseFloat(this.inputmask.unmaskedvalue()) * parseInt(pattern)); | ||
$input.trigger("setvalue"); | ||
return false; | ||
} | ||
} | ||
} | ||
if (e.ctrlKey) { | ||
switch (e.key) { | ||
case keys.ArrowUp: | ||
this.inputmask.__valueSet.call(this, parseFloat(this.inputmask.unmaskedvalue()) + parseInt(opts.step)); | ||
$input.trigger("setvalue"); | ||
return false; | ||
case keys.ArrowDown: | ||
this.inputmask.__valueSet.call(this, parseFloat(this.inputmask.unmaskedvalue()) - parseInt(opts.step)); | ||
$input.trigger("setvalue"); | ||
return false; | ||
} | ||
} | ||
if (!e.shiftKey && (e.key === keys.Delete || e.key === keys.Backspace || e.key === keys.BACKSPACE_SAFARI) && caretPos.begin !== buffer.length) { | ||
if (buffer[e.key === keys.Delete ? caretPos.begin - 1 : caretPos.end] === opts.negationSymbol.front) { | ||
bffr = buffer.slice().reverse(); | ||
if (opts.negationSymbol.front !== "") bffr.shift(); | ||
if (opts.negationSymbol.back !== "") bffr.pop(); | ||
$input.trigger("setvalue", [bffr.join(""), caretPos.begin]); | ||
return false; | ||
} else if (opts._radixDance === true) { | ||
var radixPos = buffer.indexOf(opts.radixPoint); | ||
if (!opts.digitsOptional) { | ||
if (radixPos !== -1 && (caretPos.begin < radixPos || caretPos.end < radixPos || (e.key === keys.Delete && (caretPos.begin === radixPos || caretPos.begin - 1 === radixPos)))) { | ||
var restoreCaretPos = undefined; | ||
if (caretPos.begin === caretPos.end) { //only adjust when not a selection | ||
if (e.key === keys.Backspace || e.key === keys.BACKSPACE_SAFARI) | ||
caretPos.begin++; | ||
else if (e.key === keys.Delete && caretPos.begin - 1 === radixPos) { | ||
restoreCaretPos = $.extend({}, caretPos); | ||
caretPos.begin--; | ||
caretPos.end--; | ||
} | ||
} | ||
bffr = buffer.slice().reverse(); | ||
bffr.splice(bffr.length - caretPos.begin, caretPos.begin - caretPos.end + 1); | ||
// console.log(caretPos); | ||
bffr = alignDigits(bffr, opts.digits, opts).join(""); | ||
if (restoreCaretPos) { | ||
caretPos = restoreCaretPos; | ||
} | ||
$input.trigger("setvalue", [bffr, caretPos.begin >= bffr.length ? radixPos + 1 : caretPos.begin]); | ||
return false; | ||
} | ||
} else if (radixPos === 0) { | ||
bffr = buffer.slice().reverse(); | ||
bffr.pop(); | ||
$input.trigger("setvalue", [bffr.join(""), caretPos.begin >= bffr.length ? bffr.length : caretPos.begin]); | ||
return false; | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
"currency": { | ||
prefix: "", //"$ ", | ||
groupSeparator: ",", | ||
alias: "numeric", | ||
digits: 2, | ||
digitsOptional: false | ||
}, | ||
"decimal": { | ||
alias: "numeric" | ||
}, | ||
"integer": { | ||
alias: "numeric", | ||
inputmode: "numeric", | ||
digits: 0 | ||
}, | ||
"percentage": { | ||
alias: "numeric", | ||
min: 0, | ||
max: 100, | ||
suffix: " %", | ||
digits: 0, | ||
allowMinus: false | ||
}, | ||
"indianns": { //indian numbering system | ||
alias: "numeric", | ||
_mask: function (opts) { | ||
return "(" + opts.groupSeparator + "99){*|1}(" + opts.groupSeparator + "999){1|1}"; | ||
}, | ||
groupSeparator: ",", | ||
radixPoint: ".", | ||
placeholder: "0", | ||
digits: 2, | ||
digitsOptional: false | ||
} | ||
return result; | ||
}, | ||
onKeyDown: function (e, buffer, caretPos, opts) { | ||
let $input = $(this), | ||
bffr; | ||
if (e.location != 3) { | ||
let pattern, | ||
c = e.key; | ||
if ((pattern = opts.shortcuts && opts.shortcuts[c])) { | ||
if (pattern.length > 1) { | ||
this.inputmask.__valueSet.call( | ||
this, | ||
parseFloat(this.inputmask.unmaskedvalue()) * parseInt(pattern) | ||
); | ||
$input.trigger("setvalue"); | ||
return false; | ||
} | ||
} | ||
} | ||
if (e.ctrlKey) { | ||
switch (e.key) { | ||
case keys.ArrowUp: | ||
this.inputmask.__valueSet.call( | ||
this, | ||
parseFloat(this.inputmask.unmaskedvalue()) + parseInt(opts.step) | ||
); | ||
$input.trigger("setvalue"); | ||
return false; | ||
case keys.ArrowDown: | ||
this.inputmask.__valueSet.call( | ||
this, | ||
parseFloat(this.inputmask.unmaskedvalue()) - parseInt(opts.step) | ||
); | ||
$input.trigger("setvalue"); | ||
return false; | ||
} | ||
} | ||
if ( | ||
!e.shiftKey && | ||
(e.key === keys.Delete || | ||
e.key === keys.Backspace || | ||
e.key === keys.BACKSPACE_SAFARI) && | ||
caretPos.begin !== buffer.length | ||
) { | ||
if ( | ||
buffer[e.key === keys.Delete ? caretPos.begin - 1 : caretPos.end] === | ||
opts.negationSymbol.front | ||
) { | ||
bffr = buffer.slice().reverse(); | ||
if (opts.negationSymbol.front !== "") bffr.shift(); | ||
if (opts.negationSymbol.back !== "") bffr.pop(); | ||
$input.trigger("setvalue", [bffr.join(""), caretPos.begin]); | ||
return false; | ||
} else if (opts._radixDance === true) { | ||
const radixPos = buffer.indexOf(opts.radixPoint); | ||
if (!opts.digitsOptional) { | ||
if ( | ||
radixPos !== -1 && | ||
(caretPos.begin < radixPos || | ||
caretPos.end < radixPos || | ||
(e.key === keys.Delete && | ||
(caretPos.begin === radixPos || | ||
caretPos.begin - 1 === radixPos))) | ||
) { | ||
let restoreCaretPos; | ||
if (caretPos.begin === caretPos.end) { | ||
// only adjust when not a selection | ||
if (e.key === keys.Backspace || e.key === keys.BACKSPACE_SAFARI) | ||
caretPos.begin++; | ||
else if ( | ||
e.key === keys.Delete && | ||
caretPos.begin - 1 === radixPos | ||
) { | ||
restoreCaretPos = $.extend({}, caretPos); | ||
caretPos.begin--; | ||
caretPos.end--; | ||
} | ||
} | ||
bffr = buffer.slice().reverse(); | ||
bffr.splice( | ||
bffr.length - caretPos.begin, | ||
caretPos.begin - caretPos.end + 1 | ||
); | ||
// console.log(caretPos); | ||
bffr = alignDigits(bffr, opts.digits, opts).join(""); | ||
if (restoreCaretPos) { | ||
caretPos = restoreCaretPos; | ||
} | ||
$input.trigger("setvalue", [ | ||
bffr, | ||
caretPos.begin >= bffr.length ? radixPos + 1 : caretPos.begin | ||
]); | ||
return false; | ||
} | ||
} else if (radixPos === 0) { | ||
bffr = buffer.slice().reverse(); | ||
bffr.pop(); | ||
$input.trigger("setvalue", [ | ||
bffr.join(""), | ||
caretPos.begin >= bffr.length ? bffr.length : caretPos.begin | ||
]); | ||
return false; | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
currency: { | ||
prefix: "", // "$ ", | ||
groupSeparator: ",", | ||
alias: "numeric", | ||
digits: 2, | ||
digitsOptional: false | ||
}, | ||
decimal: { | ||
alias: "numeric" | ||
}, | ||
integer: { | ||
alias: "numeric", | ||
inputmode: "numeric", | ||
digits: 0 | ||
}, | ||
percentage: { | ||
alias: "numeric", | ||
min: 0, | ||
max: 100, | ||
suffix: " %", | ||
digits: 0, | ||
allowMinus: false | ||
}, | ||
indianns: { | ||
// indian numbering system | ||
alias: "numeric", | ||
_mask: function (opts) { | ||
return ( | ||
"(" + | ||
opts.groupSeparator + | ||
"99){*|1}(" + | ||
opts.groupSeparator + | ||
"999){1|1}" | ||
); | ||
}, | ||
groupSeparator: ",", | ||
radixPoint: ".", | ||
placeholder: "0", | ||
digits: 2, | ||
digitsOptional: false | ||
} | ||
}); |
const canUseDOM = !!( | ||
typeof window !== "undefined" && | ||
window.document && | ||
window.document.createElement | ||
typeof window !== "undefined" && | ||
window.document && | ||
window.document.createElement | ||
); | ||
export default canUseDOM ? window : {}; |
@@ -1,255 +0,417 @@ | ||
import {keys} from "./keycode.js"; | ||
import {getMaskTemplate, getPlaceholder, getTest} from "./validation-tests"; | ||
import { ie } from "./environment"; | ||
import { EventHandlers } from "./eventhandlers"; | ||
import { keys } from "./keycode.js"; | ||
import { | ||
caret, | ||
determineNewCaretPosition, | ||
getBuffer, getBufferTemplate, | ||
getLastValidPosition, | ||
isMask, | ||
resetMaskSet, | ||
seekNext | ||
caret, | ||
determineNewCaretPosition, | ||
getBuffer, | ||
getBufferTemplate, | ||
getLastValidPosition, | ||
isMask, | ||
resetMaskSet, | ||
seekNext | ||
} from "./positioning"; | ||
import {isComplete, refreshFromBuffer} from "./validation"; | ||
import {ie} from "./environment"; | ||
import {EventHandlers} from "./eventhandlers"; | ||
import { isComplete, refreshFromBuffer } from "./validation"; | ||
import { getMaskTemplate, getPlaceholder, getTest } from "./validation-tests"; | ||
export {applyInputValue, clearOptionalTail, checkVal, HandleNativePlaceholder, unmaskedvalue, writeBuffer}; | ||
export { | ||
applyInputValue, | ||
clearOptionalTail, | ||
checkVal, | ||
HandleNativePlaceholder, | ||
unmaskedvalue, | ||
writeBuffer | ||
}; | ||
function applyInputValue(input, value, initialEvent) { | ||
const inputmask = input ? input.inputmask : this, opts = inputmask.opts; | ||
const inputmask = input ? input.inputmask : this, | ||
opts = inputmask.opts; | ||
input.inputmask.refreshValue = false; | ||
if (typeof opts.onBeforeMask === "function") value = opts.onBeforeMask.call(inputmask, value, opts) || value; | ||
value = (value || "").toString().split(""); | ||
checkVal(input, true, false, value, initialEvent); | ||
inputmask.undoValue = inputmask._valueGet(true); | ||
if ((opts.clearMaskOnLostFocus || opts.clearIncomplete) && input.inputmask._valueGet() === getBufferTemplate.call(inputmask).join("") && getLastValidPosition.call(inputmask) === -1) { | ||
input.inputmask._valueSet(""); | ||
} | ||
input.inputmask.refreshValue = false; | ||
if (typeof opts.onBeforeMask === "function") | ||
value = opts.onBeforeMask.call(inputmask, value, opts) || value; | ||
value = (value || "").toString().split(""); | ||
checkVal(input, true, false, value, initialEvent); | ||
inputmask.undoValue = inputmask._valueGet(true); | ||
if ( | ||
(opts.clearMaskOnLostFocus || opts.clearIncomplete) && | ||
input.inputmask._valueGet() === | ||
getBufferTemplate.call(inputmask).join("") && | ||
getLastValidPosition.call(inputmask) === -1 | ||
) { | ||
input.inputmask._valueSet(""); | ||
} | ||
} | ||
//todo put on prototype? | ||
// todo put on prototype? | ||
function clearOptionalTail(buffer) { | ||
const inputmask = this; | ||
const inputmask = this; | ||
buffer.length = 0; | ||
var template = getMaskTemplate.call(inputmask, true, 0, true, undefined, true), lmnt; | ||
while ((lmnt = template.shift()) !== undefined) buffer.push(lmnt); | ||
return buffer; | ||
buffer.length = 0; | ||
let template = getMaskTemplate.call( | ||
inputmask, | ||
true, | ||
0, | ||
true, | ||
undefined, | ||
true | ||
), | ||
lmnt; | ||
while ((lmnt = template.shift()) !== undefined) buffer.push(lmnt); | ||
return buffer; | ||
} | ||
function checkVal(input, writeOut, strict, nptvl, initiatingEvent) { | ||
const inputmask = input ? input.inputmask : this, | ||
maskset = inputmask.maskset, | ||
opts = inputmask.opts, $ = inputmask.dependencyLib; | ||
const inputmask = input ? input.inputmask : this, | ||
maskset = inputmask.maskset, | ||
opts = inputmask.opts, | ||
$ = inputmask.dependencyLib; | ||
var inputValue = nptvl.slice(), | ||
charCodes = "", | ||
initialNdx = -1, | ||
result = undefined, skipOptionalPartCharacter = opts.skipOptionalPartCharacter; | ||
opts.skipOptionalPartCharacter = ""; //see issue #2311 | ||
let inputValue = nptvl.slice(), | ||
charCodes = "", | ||
initialNdx = -1, | ||
result, | ||
skipOptionalPartCharacter = opts.skipOptionalPartCharacter; | ||
opts.skipOptionalPartCharacter = ""; // see issue #2311 | ||
function isTemplateMatch(ndx, charCodes) { | ||
var targetTemplate = getMaskTemplate.call(inputmask, true, 0).slice(ndx, seekNext.call(inputmask, ndx, false, false)).join("").replace(/'/g, ""), | ||
charCodeNdx = targetTemplate.indexOf(charCodes); | ||
//strip spaces from targetTemplate | ||
while (charCodeNdx > 0 && targetTemplate[charCodeNdx - 1] === " ") charCodeNdx--; | ||
function isTemplateMatch(ndx, charCodes) { | ||
let targetTemplate = getMaskTemplate | ||
.call(inputmask, true, 0) | ||
.slice(ndx, seekNext.call(inputmask, ndx, false, false)) | ||
.join("") | ||
.replace(/'/g, ""), | ||
charCodeNdx = targetTemplate.indexOf(charCodes); | ||
// strip spaces from targetTemplate | ||
while (charCodeNdx > 0 && targetTemplate[charCodeNdx - 1] === " ") | ||
charCodeNdx--; | ||
var match = charCodeNdx === 0 && !isMask.call(inputmask, ndx) | ||
&& (getTest.call(inputmask, ndx).match.nativeDef === charCodes.charAt(0) | ||
|| (getTest.call(inputmask, ndx).match.static === true && getTest.call(inputmask, ndx).match.nativeDef === ("'" + charCodes.charAt(0))) | ||
|| (getTest.call(inputmask, ndx).match.nativeDef === " " && (getTest.call(inputmask, ndx + 1).match.nativeDef === charCodes.charAt(0) | ||
|| (getTest.call(inputmask, ndx + 1).match.static === true && getTest.call(inputmask, ndx + 1).match.nativeDef === ("'" + charCodes.charAt(0)))))); | ||
const match = | ||
charCodeNdx === 0 && | ||
!isMask.call(inputmask, ndx) && | ||
(getTest.call(inputmask, ndx).match.nativeDef === charCodes.charAt(0) || | ||
(getTest.call(inputmask, ndx).match.static === true && | ||
getTest.call(inputmask, ndx).match.nativeDef === | ||
"'" + charCodes.charAt(0)) || | ||
(getTest.call(inputmask, ndx).match.nativeDef === " " && | ||
(getTest.call(inputmask, ndx + 1).match.nativeDef === | ||
charCodes.charAt(0) || | ||
(getTest.call(inputmask, ndx + 1).match.static === true && | ||
getTest.call(inputmask, ndx + 1).match.nativeDef === | ||
"'" + charCodes.charAt(0))))); | ||
if (!match && charCodeNdx > 0 && !isMask.call(inputmask, ndx, false, true)) { | ||
var nextPos = seekNext.call(inputmask, ndx); | ||
if (inputmask.caretPos.begin < nextPos) { | ||
inputmask.caretPos = {begin: nextPos}; | ||
} | ||
} | ||
return match; | ||
} | ||
if ( | ||
!match && | ||
charCodeNdx > 0 && | ||
!isMask.call(inputmask, ndx, false, true) | ||
) { | ||
const nextPos = seekNext.call(inputmask, ndx); | ||
if (inputmask.caretPos.begin < nextPos) { | ||
inputmask.caretPos = { begin: nextPos }; | ||
} | ||
} | ||
return match; | ||
} | ||
resetMaskSet.call(inputmask, false); | ||
inputmask.clicked = 0; //reset click counter to correctly determine the caretposition in checkval | ||
initialNdx = opts.radixPoint ? determineNewCaretPosition.call(inputmask, { | ||
begin: 0, | ||
end: 0 | ||
}, false, opts.__financeInput === false ? "radixFocus" : undefined).begin : 0; | ||
maskset.p = initialNdx; | ||
inputmask.caretPos = {begin: initialNdx}; | ||
resetMaskSet.call(inputmask, false); | ||
inputmask.clicked = 0; // reset click counter to correctly determine the caretposition in checkval | ||
initialNdx = opts.radixPoint | ||
? determineNewCaretPosition.call( | ||
inputmask, | ||
{ | ||
begin: 0, | ||
end: 0 | ||
}, | ||
false, | ||
opts.__financeInput === false ? "radixFocus" : undefined | ||
).begin | ||
: 0; | ||
maskset.p = initialNdx; | ||
inputmask.caretPos = { begin: initialNdx }; | ||
var staticMatches = [], prevCaretPos = inputmask.caretPos; | ||
inputValue.forEach(function (charCode, ndx) { | ||
if (charCode !== undefined) { //inputfallback strips some elements out of the inputarray. $.each logically presents them as undefined | ||
/*if (maskset.validPositions[ndx] === undefined && inputValue[ndx] === getPlaceholder.call(inputmask, ndx) && isMask.call(inputmask, ndx, true) && | ||
let staticMatches = [], | ||
prevCaretPos = inputmask.caretPos; | ||
inputValue.forEach(function (charCode, ndx) { | ||
if (charCode !== undefined) { | ||
// inputfallback strips some elements out of the inputarray. $.each logically presents them as undefined | ||
/* if (maskset.validPositions[ndx] === undefined && inputValue[ndx] === getPlaceholder.call(inputmask, ndx) && isMask.call(inputmask, ndx, true) && | ||
isValid.call(inputmask, ndx, inputValue[ndx], true, undefined, true, true) === false) { | ||
inputmask.caretPos.begin++; | ||
} else*/ | ||
{ | ||
// console.log("caret " + inputmask.caretPos.begin); | ||
var keypress = new $.Event("_checkval"); | ||
keypress.key = charCode; | ||
charCodes += charCode; | ||
var lvp = getLastValidPosition.call(inputmask, undefined, true); | ||
if (!isTemplateMatch(initialNdx, charCodes)) { | ||
result = EventHandlers.keypressEvent.call(inputmask, keypress, true, false, strict, inputmask.caretPos.begin); | ||
} else */ | ||
// console.log("caret " + inputmask.caretPos.begin); | ||
const keypress = new $.Event("_checkval"); | ||
keypress.key = charCode; | ||
charCodes += charCode; | ||
const lvp = getLastValidPosition.call(inputmask, undefined, true); | ||
if (!isTemplateMatch(initialNdx, charCodes)) { | ||
result = EventHandlers.keypressEvent.call( | ||
inputmask, | ||
keypress, | ||
true, | ||
false, | ||
strict, | ||
inputmask.caretPos.begin | ||
); | ||
if (result) { | ||
initialNdx = inputmask.caretPos.begin + 1; | ||
charCodes = ""; | ||
} | ||
} else { | ||
result = EventHandlers.keypressEvent.call(inputmask, keypress, true, false, strict, lvp + 1); | ||
} | ||
if (result) { | ||
if (result.pos !== undefined && maskset.validPositions[result.pos] && maskset.validPositions[result.pos].match.static === true && maskset.validPositions[result.pos].alternation === undefined) { | ||
staticMatches.push(result.pos); | ||
if (!inputmask.isRTL) { | ||
result.forwardPosition = result.pos + 1; | ||
} | ||
} | ||
writeBuffer.call(inputmask, undefined, getBuffer.call(inputmask), result.forwardPosition, keypress, false); | ||
inputmask.caretPos = {begin: result.forwardPosition, end: result.forwardPosition}; | ||
prevCaretPos = inputmask.caretPos; | ||
} else { | ||
if (maskset.validPositions[ndx] === undefined && inputValue[ndx] === getPlaceholder.call(inputmask, ndx) && isMask.call(inputmask, ndx, true)) { | ||
inputmask.caretPos.begin++; | ||
} else inputmask.caretPos = prevCaretPos; //restore the caret position from before the failed validation | ||
} | ||
} | ||
} | ||
}); | ||
if (staticMatches.length > 0) { | ||
var sndx, validPos, nextValid = seekNext.call(inputmask, -1, undefined, false); | ||
if ((!isComplete.call(inputmask, getBuffer.call(inputmask)) && staticMatches.length <= nextValid) | ||
|| (isComplete.call(inputmask, getBuffer.call(inputmask)) && staticMatches.length > 0 && (staticMatches.length !== nextValid && staticMatches[0] === 0))) { //should check if is sequence starting from 0 | ||
var nextSndx = nextValid; | ||
while ((sndx = staticMatches.shift()) !== undefined) { | ||
if (sndx < nextSndx) { | ||
var keypress = new $.Event("_checkval"); | ||
validPos = maskset.validPositions[sndx]; | ||
validPos.generatedInput = true; | ||
keypress.key = validPos.input; | ||
result = EventHandlers.keypressEvent.call(inputmask, keypress, true, false, strict, nextSndx); | ||
if (result && result.pos !== undefined && result.pos !== sndx && maskset.validPositions[result.pos] && maskset.validPositions[result.pos].match.static === true) { | ||
staticMatches.push(result.pos); | ||
} else if (!result) break; | ||
nextSndx++; | ||
} | ||
} | ||
} else { //mark al statics as generated | ||
// while ((sndx = staticMatches.pop())) { | ||
// validPos = maskset.validPositions[sndx]; | ||
// if (validPos) { | ||
// validPos.generatedInput = true; | ||
// } | ||
// } | ||
} | ||
} | ||
if (writeOut) { | ||
writeBuffer.call( | ||
inputmask, | ||
input, | ||
getBuffer.call(inputmask), result ? result.forwardPosition : inputmask.caretPos.begin, | ||
initiatingEvent || new $.Event("checkval"), | ||
initiatingEvent && ((initiatingEvent.type === "input" && inputmask.undoValue !== getBuffer.call(inputmask).join("")) || initiatingEvent.type === "paste")); | ||
// for (var vndx in maskset.validPositions) { | ||
// if (maskset.validPositions[vndx].match.generated !== true) { //only remove non forced generated | ||
// delete maskset.validPositions[vndx].generatedInput; //clear generated markings ~ consider initializing with a value as fully typed | ||
// } | ||
// } | ||
} | ||
opts.skipOptionalPartCharacter = skipOptionalPartCharacter; | ||
if (result) { | ||
initialNdx = inputmask.caretPos.begin + 1; | ||
charCodes = ""; | ||
} | ||
} else { | ||
result = EventHandlers.keypressEvent.call( | ||
inputmask, | ||
keypress, | ||
true, | ||
false, | ||
strict, | ||
lvp + 1 | ||
); | ||
} | ||
if (result) { | ||
if ( | ||
result.pos !== undefined && | ||
maskset.validPositions[result.pos] && | ||
maskset.validPositions[result.pos].match.static === true && | ||
maskset.validPositions[result.pos].alternation === undefined | ||
) { | ||
staticMatches.push(result.pos); | ||
if (!inputmask.isRTL) { | ||
result.forwardPosition = result.pos + 1; | ||
} | ||
} | ||
writeBuffer.call( | ||
inputmask, | ||
undefined, | ||
getBuffer.call(inputmask), | ||
result.forwardPosition, | ||
keypress, | ||
false | ||
); | ||
inputmask.caretPos = { | ||
begin: result.forwardPosition, | ||
end: result.forwardPosition | ||
}; | ||
prevCaretPos = inputmask.caretPos; | ||
} else { | ||
if ( | ||
maskset.validPositions[ndx] === undefined && | ||
inputValue[ndx] === getPlaceholder.call(inputmask, ndx) && | ||
isMask.call(inputmask, ndx, true) | ||
) { | ||
inputmask.caretPos.begin++; | ||
} else inputmask.caretPos = prevCaretPos; // restore the caret position from before the failed validation | ||
} | ||
} | ||
}); | ||
if (staticMatches.length > 0) { | ||
let sndx, | ||
validPos, | ||
nextValid = seekNext.call(inputmask, -1, undefined, false); | ||
if ( | ||
(!isComplete.call(inputmask, getBuffer.call(inputmask)) && | ||
staticMatches.length <= nextValid) || | ||
(isComplete.call(inputmask, getBuffer.call(inputmask)) && | ||
staticMatches.length > 0 && | ||
staticMatches.length !== nextValid && | ||
staticMatches[0] === 0) | ||
) { | ||
// should check if is sequence starting from 0 | ||
let nextSndx = nextValid; | ||
while ((sndx = staticMatches.shift()) !== undefined) { | ||
if (sndx < nextSndx) { | ||
const keypress = new $.Event("_checkval"); | ||
validPos = maskset.validPositions[sndx]; | ||
validPos.generatedInput = true; | ||
keypress.key = validPos.input; | ||
result = EventHandlers.keypressEvent.call( | ||
inputmask, | ||
keypress, | ||
true, | ||
false, | ||
strict, | ||
nextSndx | ||
); | ||
if ( | ||
result && | ||
result.pos !== undefined && | ||
result.pos !== sndx && | ||
maskset.validPositions[result.pos] && | ||
maskset.validPositions[result.pos].match.static === true | ||
) { | ||
staticMatches.push(result.pos); | ||
} else if (!result) break; | ||
nextSndx++; | ||
} | ||
} | ||
} else { | ||
// mark al statics as generated | ||
// while ((sndx = staticMatches.pop())) { | ||
// validPos = maskset.validPositions[sndx]; | ||
// if (validPos) { | ||
// validPos.generatedInput = true; | ||
// } | ||
// } | ||
} | ||
} | ||
if (writeOut) { | ||
writeBuffer.call( | ||
inputmask, | ||
input, | ||
getBuffer.call(inputmask), | ||
result ? result.forwardPosition : inputmask.caretPos.begin, | ||
initiatingEvent || new $.Event("checkval"), | ||
initiatingEvent && | ||
((initiatingEvent.type === "input" && | ||
inputmask.undoValue !== getBuffer.call(inputmask).join("")) || | ||
initiatingEvent.type === "paste") | ||
); | ||
// for (var vndx in maskset.validPositions) { | ||
// if (maskset.validPositions[vndx].match.generated !== true) { //only remove non forced generated | ||
// delete maskset.validPositions[vndx].generatedInput; //clear generated markings ~ consider initializing with a value as fully typed | ||
// } | ||
// } | ||
} | ||
opts.skipOptionalPartCharacter = skipOptionalPartCharacter; | ||
} | ||
function HandleNativePlaceholder(npt, value) { | ||
const inputmask = npt ? npt.inputmask : this; | ||
const inputmask = npt ? npt.inputmask : this; | ||
if (ie) { | ||
if (npt.inputmask._valueGet() !== value && (npt.placeholder !== value || npt.placeholder === "")) { | ||
var buffer = getBuffer.call(inputmask).slice(), | ||
nptValue = npt.inputmask._valueGet(); | ||
if (nptValue !== value) { | ||
var lvp = getLastValidPosition.call(inputmask); | ||
if (lvp === -1 && nptValue === getBufferTemplate.call(inputmask).join("")) { | ||
buffer = []; | ||
} else if (lvp !== -1) { //clearout optional tail of the mask | ||
clearOptionalTail.call(inputmask, buffer); | ||
} | ||
writeBuffer(npt, buffer); | ||
} | ||
} | ||
} else if (npt.placeholder !== value) { | ||
npt.placeholder = value; | ||
if (npt.placeholder === "") npt.removeAttribute("placeholder"); | ||
} | ||
if (ie) { | ||
if ( | ||
npt.inputmask._valueGet() !== value && | ||
(npt.placeholder !== value || npt.placeholder === "") | ||
) { | ||
let buffer = getBuffer.call(inputmask).slice(), | ||
nptValue = npt.inputmask._valueGet(); | ||
if (nptValue !== value) { | ||
const lvp = getLastValidPosition.call(inputmask); | ||
if ( | ||
lvp === -1 && | ||
nptValue === getBufferTemplate.call(inputmask).join("") | ||
) { | ||
buffer = []; | ||
} else if (lvp !== -1) { | ||
// clearout optional tail of the mask | ||
clearOptionalTail.call(inputmask, buffer); | ||
} | ||
writeBuffer(npt, buffer); | ||
} | ||
} | ||
} else if (npt.placeholder !== value) { | ||
npt.placeholder = value; | ||
if (npt.placeholder === "") npt.removeAttribute("placeholder"); | ||
} | ||
} | ||
function unmaskedvalue(input) { | ||
const inputmask = input ? input.inputmask : this, | ||
opts = inputmask.opts, | ||
maskset = inputmask.maskset; | ||
const inputmask = input ? input.inputmask : this, | ||
opts = inputmask.opts, | ||
maskset = inputmask.maskset; | ||
if (input) { | ||
if (input.inputmask === undefined) { | ||
return input.value; | ||
} | ||
if (input.inputmask && input.inputmask.refreshValue) { //forced refresh from the value form.reset | ||
applyInputValue(input, input.inputmask._valueGet(true)); | ||
} | ||
} | ||
var umValue = [], | ||
vps = maskset.validPositions; | ||
for (let pndx = 0, vpl = vps.length; pndx < vpl; pndx++) { | ||
if (vps[pndx] && vps[pndx].match && (vps[pndx].match.static != true || (Array.isArray(maskset.metadata) && vps[pndx].generatedInput !== true))) { | ||
//only include generated input with multiple masks (check on metadata) | ||
umValue.push(vps[pndx].input); | ||
} | ||
} | ||
var unmaskedValue = umValue.length === 0 ? "" : (inputmask.isRTL ? umValue.reverse() : umValue).join(""); | ||
if (typeof opts.onUnMask === "function") { | ||
var bufferValue = (inputmask.isRTL ? getBuffer.call(inputmask).slice().reverse() : getBuffer.call(inputmask)).join(""); | ||
unmaskedValue = opts.onUnMask.call(inputmask, bufferValue, unmaskedValue, opts); | ||
} | ||
return unmaskedValue; | ||
if (input) { | ||
if (input.inputmask === undefined) { | ||
return input.value; | ||
} | ||
if (input.inputmask && input.inputmask.refreshValue) { | ||
// forced refresh from the value form.reset | ||
applyInputValue(input, input.inputmask._valueGet(true)); | ||
} | ||
} | ||
const umValue = [], | ||
vps = maskset.validPositions; | ||
for (let pndx = 0, vpl = vps.length; pndx < vpl; pndx++) { | ||
if ( | ||
vps[pndx] && | ||
vps[pndx].match && | ||
(vps[pndx].match.static != true || | ||
(Array.isArray(maskset.metadata) && vps[pndx].generatedInput !== true)) | ||
) { | ||
// only include generated input with multiple masks (check on metadata) | ||
umValue.push(vps[pndx].input); | ||
} | ||
} | ||
let unmaskedValue = | ||
umValue.length === 0 | ||
? "" | ||
: (inputmask.isRTL ? umValue.reverse() : umValue).join(""); | ||
if (typeof opts.onUnMask === "function") { | ||
const bufferValue = ( | ||
inputmask.isRTL | ||
? getBuffer.call(inputmask).slice().reverse() | ||
: getBuffer.call(inputmask) | ||
).join(""); | ||
unmaskedValue = opts.onUnMask.call( | ||
inputmask, | ||
bufferValue, | ||
unmaskedValue, | ||
opts | ||
); | ||
} | ||
return unmaskedValue; | ||
} | ||
function writeBuffer(input, buffer, caretPos, event, triggerEvents) { | ||
const inputmask = input ? input.inputmask : this, | ||
opts = inputmask.opts, | ||
$ = inputmask.dependencyLib; | ||
const inputmask = input ? input.inputmask : this, | ||
opts = inputmask.opts, | ||
$ = inputmask.dependencyLib; | ||
if (event && typeof opts.onBeforeWrite === "function") { | ||
// buffer = buffer.slice(); //prevent uncontrolled manipulation of the internal buffer | ||
var result = opts.onBeforeWrite.call(inputmask, event, buffer, caretPos, opts); | ||
if (result) { | ||
if (result.refreshFromBuffer) { | ||
var refresh = result.refreshFromBuffer; | ||
refreshFromBuffer.call(inputmask, refresh === true ? refresh : refresh.start, refresh.end, result.buffer || buffer); | ||
buffer = getBuffer.call(inputmask, true); | ||
} | ||
if (caretPos !== undefined) caretPos = result.caret !== undefined ? result.caret : caretPos; | ||
} | ||
} | ||
if (input !== undefined) { | ||
input.inputmask._valueSet(buffer.join("")); | ||
if (caretPos !== undefined && (event === undefined || event.type !== "blur")) { | ||
// console.log(caretPos); | ||
caret.call(inputmask, input, caretPos, undefined, undefined, (event !== undefined && event.type === "keydown" && (event.key === keys.Delete || event.key === keys.Backspace))); | ||
} | ||
input.inputmask.writeBufferHook === undefined || input.inputmask.writeBufferHook(caretPos); | ||
if (triggerEvents === true) { | ||
var $input = $(input), nptVal = input.inputmask._valueGet(); | ||
input.inputmask.skipInputEvent = true; | ||
$input.trigger("input"); | ||
setTimeout(function () { //timeout needed for IE | ||
if (nptVal === getBufferTemplate.call(inputmask).join("")) { | ||
$input.trigger("cleared"); | ||
} else if (isComplete.call(inputmask, buffer) === true) { | ||
$input.trigger("complete"); | ||
} | ||
}, 0); | ||
} | ||
} | ||
if (event && typeof opts.onBeforeWrite === "function") { | ||
// buffer = buffer.slice(); //prevent uncontrolled manipulation of the internal buffer | ||
const result = opts.onBeforeWrite.call( | ||
inputmask, | ||
event, | ||
buffer, | ||
caretPos, | ||
opts | ||
); | ||
if (result) { | ||
if (result.refreshFromBuffer) { | ||
const refresh = result.refreshFromBuffer; | ||
refreshFromBuffer.call( | ||
inputmask, | ||
refresh === true ? refresh : refresh.start, | ||
refresh.end, | ||
result.buffer || buffer | ||
); | ||
buffer = getBuffer.call(inputmask, true); | ||
} | ||
if (caretPos !== undefined) | ||
caretPos = result.caret !== undefined ? result.caret : caretPos; | ||
} | ||
} | ||
if (input !== undefined) { | ||
input.inputmask._valueSet(buffer.join("")); | ||
if ( | ||
caretPos !== undefined && | ||
(event === undefined || event.type !== "blur") | ||
) { | ||
// console.log(caretPos); | ||
caret.call( | ||
inputmask, | ||
input, | ||
caretPos, | ||
undefined, | ||
undefined, | ||
event !== undefined && | ||
event.type === "keydown" && | ||
(event.key === keys.Delete || event.key === keys.Backspace) | ||
); | ||
} | ||
input.inputmask.writeBufferHook === undefined || | ||
input.inputmask.writeBufferHook(caretPos); | ||
if (triggerEvents === true) { | ||
const $input = $(input), | ||
nptVal = input.inputmask._valueGet(); | ||
input.inputmask.skipInputEvent = true; | ||
$input.trigger("input"); | ||
setTimeout(function () { | ||
// timeout needed for IE | ||
if (nptVal === getBufferTemplate.call(inputmask).join("")) { | ||
$input.trigger("cleared"); | ||
} else if (isComplete.call(inputmask, buffer) === true) { | ||
$input.trigger("complete"); | ||
} | ||
}, 0); | ||
} | ||
} | ||
} |
@@ -8,338 +8,420 @@ /* | ||
import {mask} from "./mask"; | ||
import defaults from "./defaults"; | ||
import definitions from "./definitions"; | ||
import $ from "./dependencyLibs/inputmask.dependencyLib"; | ||
import { EventRuler } from "./eventruler"; | ||
import window from "./global/window"; | ||
import {generateMaskSet, analyseMask} from "./mask-lexer"; | ||
import {getMaskTemplate} from "./validation-tests"; | ||
import {determineLastRequiredPosition, getBuffer, getBufferTemplate, isMask} from "./positioning"; | ||
import {isComplete} from "./validation"; | ||
import {checkVal, unmaskedvalue} from "./inputHandling"; | ||
import {EventRuler} from "./eventruler"; | ||
import definitions from "./definitions"; | ||
import defaults from "./defaults"; | ||
import { checkVal, unmaskedvalue } from "./inputHandling"; | ||
import { mask } from "./mask"; | ||
import { generateMaskSet, analyseMask } from "./mask-lexer"; | ||
import { | ||
determineLastRequiredPosition, | ||
getBuffer, | ||
getBufferTemplate, | ||
isMask | ||
} from "./positioning"; | ||
import { isComplete } from "./validation"; | ||
import { getMaskTemplate } from "./validation-tests"; | ||
const document = window.document, dataKey = "_inputmask_opts"; | ||
const document = window.document, | ||
dataKey = "_inputmask_opts"; | ||
function Inputmask(alias, options, internal) { | ||
//allow instanciating without new | ||
if (!(this instanceof Inputmask)) { | ||
return new Inputmask(alias, options, internal); | ||
} | ||
// allow instanciating without new | ||
if (!(this instanceof Inputmask)) { | ||
return new Inputmask(alias, options, internal); | ||
} | ||
this.dependencyLib = $; | ||
this.el = undefined; | ||
this.events = {}; | ||
this.maskset = undefined; | ||
this.dependencyLib = $; | ||
this.el = undefined; | ||
this.events = {}; | ||
this.maskset = undefined; | ||
if (internal !== true) { | ||
//init options | ||
if (Object.prototype.toString.call(alias) === "[object Object]") { | ||
options = alias; | ||
} else { | ||
options = options || {}; | ||
if (alias) options.alias = alias; | ||
} | ||
this.opts = $.extend(true, {}, this.defaults, options); | ||
this.noMasksCache = options && options.definitions !== undefined; | ||
this.userOptions = options || {}; //user passed options | ||
resolveAlias(this.opts.alias, options, this.opts); | ||
} | ||
if (internal !== true) { | ||
// init options | ||
if (Object.prototype.toString.call(alias) === "[object Object]") { | ||
options = alias; | ||
} else { | ||
options = options || {}; | ||
if (alias) options.alias = alias; | ||
} | ||
this.opts = $.extend(true, {}, this.defaults, options); | ||
this.noMasksCache = options && options.definitions !== undefined; | ||
this.userOptions = options || {}; // user passed options | ||
resolveAlias(this.opts.alias, options, this.opts); | ||
} | ||
//maskscope properties | ||
this.refreshValue = false; //indicate a refresh from the inputvalue is needed (form.reset) | ||
this.undoValue = undefined; | ||
this.$el = undefined; | ||
this.skipInputEvent = false; //skip when triggered from within inputmask | ||
this.validationEvent = false; | ||
this.ignorable = false; | ||
this.maxLength; | ||
this.mouseEnter = false; | ||
this.clicked = 0; | ||
this.originalPlaceholder = undefined; //needed for FF | ||
this.isComposing = false, //keydowncode == 229 compositionevent fallback | ||
this.hasAlternator = false; | ||
// maskscope properties | ||
this.refreshValue = false; // indicate a refresh from the inputvalue is needed (form.reset) | ||
this.undoValue = undefined; | ||
this.$el = undefined; | ||
this.skipInputEvent = false; // skip when triggered from within inputmask | ||
this.validationEvent = false; | ||
this.ignorable = false; | ||
// eslint-disable-next-line no-unused-expressions | ||
this.maxLength; | ||
this.mouseEnter = false; | ||
this.clicked = 0; | ||
this.originalPlaceholder = undefined; // needed for FF | ||
this.isComposing = false; // keydowncode == 229 compositionevent fallback | ||
this.hasAlternator = false; | ||
} | ||
Inputmask.prototype = { | ||
dataAttribute: "data-inputmask", //data attribute prefix used for attribute binding | ||
//options default | ||
defaults: defaults, | ||
definitions: definitions, | ||
aliases: {}, //aliases definitions | ||
masksCache: {}, | ||
i18n: {}, | ||
get isRTL() { | ||
return this.opts.isRTL || this.opts.numericInput; | ||
}, | ||
mask: function (elems) { | ||
var that = this; | ||
if (typeof elems === "string") { | ||
elems = (document.getElementById(elems) || document.querySelectorAll(elems)); | ||
} | ||
elems = elems.nodeName ? [elems] : (Array.isArray(elems) ? elems : [].slice.call(elems)); //[].slice as alternate for Array.from (Yandex browser) | ||
elems.forEach(function (el, ndx) { | ||
var scopedOpts = $.extend(true, {}, that.opts); | ||
if (importAttributeOptions(el, scopedOpts, $.extend(true, {}, that.userOptions), that.dataAttribute)) { | ||
var maskset = generateMaskSet(scopedOpts, that.noMasksCache); | ||
if (maskset !== undefined) { | ||
if (el.inputmask !== undefined) { | ||
el.inputmask.opts.autoUnmask = true; //force autounmasking when remasking | ||
el.inputmask.remove(); | ||
} | ||
//store inputmask instance on the input with element reference | ||
el.inputmask = new Inputmask(undefined, undefined, true); | ||
el.inputmask.opts = scopedOpts; | ||
el.inputmask.noMasksCache = that.noMasksCache; | ||
el.inputmask.userOptions = $.extend(true, {}, that.userOptions); | ||
// el.inputmask.isRTL = scopedOpts.isRTL || scopedOpts.numericInput; | ||
el.inputmask.el = el; | ||
el.inputmask.$el = $(el); | ||
el.inputmask.maskset = maskset; | ||
dataAttribute: "data-inputmask", // data attribute prefix used for attribute binding | ||
// options default | ||
defaults, | ||
definitions, | ||
aliases: {}, // aliases definitions | ||
masksCache: {}, | ||
i18n: {}, | ||
get isRTL() { | ||
return this.opts.isRTL || this.opts.numericInput; | ||
}, | ||
mask: function (elems) { | ||
const that = this; | ||
if (typeof elems === "string") { | ||
elems = | ||
document.getElementById(elems) || document.querySelectorAll(elems); | ||
} | ||
elems = elems.nodeName | ||
? [elems] | ||
: Array.isArray(elems) | ||
? elems | ||
: [].slice.call(elems); // [].slice as alternate for Array.from (Yandex browser) | ||
elems.forEach(function (el, ndx) { | ||
const scopedOpts = $.extend(true, {}, that.opts); | ||
if ( | ||
importAttributeOptions( | ||
el, | ||
scopedOpts, | ||
$.extend(true, {}, that.userOptions), | ||
that.dataAttribute | ||
) | ||
) { | ||
const maskset = generateMaskSet(scopedOpts, that.noMasksCache); | ||
if (maskset !== undefined) { | ||
if (el.inputmask !== undefined) { | ||
el.inputmask.opts.autoUnmask = true; // force autounmasking when remasking | ||
el.inputmask.remove(); | ||
} | ||
// store inputmask instance on the input with element reference | ||
el.inputmask = new Inputmask(undefined, undefined, true); | ||
el.inputmask.opts = scopedOpts; | ||
el.inputmask.noMasksCache = that.noMasksCache; | ||
el.inputmask.userOptions = $.extend(true, {}, that.userOptions); | ||
// el.inputmask.isRTL = scopedOpts.isRTL || scopedOpts.numericInput; | ||
el.inputmask.el = el; | ||
el.inputmask.$el = $(el); | ||
el.inputmask.maskset = maskset; | ||
$.data(el, dataKey, that.userOptions); | ||
mask.call(el.inputmask); | ||
} | ||
} | ||
}); | ||
return elems && elems[0] ? (elems[0].inputmask || this) : this; | ||
}, | ||
option: function (options, noremask) { //set extra options || retrieve value of a current option | ||
if (typeof options === "string") { | ||
return this.opts[options]; | ||
} else if (typeof options === "object") { | ||
$.extend(this.userOptions, options); //user passed options | ||
//remask | ||
if (this.el && noremask !== true) { | ||
this.mask(this.el); | ||
} | ||
return this; | ||
} | ||
}, | ||
unmaskedvalue: function (value) { | ||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
if (this.el === undefined || value !== undefined) { | ||
var valueBuffer = (typeof this.opts.onBeforeMask === "function" ? (this.opts.onBeforeMask.call(this, value, this.opts) || value) : value).split(""); | ||
checkVal.call(this, undefined, false, false, valueBuffer); | ||
if (typeof this.opts.onBeforeWrite === "function") this.opts.onBeforeWrite.call(this, undefined, getBuffer.call(this), 0, this.opts); | ||
} | ||
return unmaskedvalue.call(this, this.el); | ||
}, | ||
remove: function () { | ||
if (this.el) { | ||
$.data(this.el, dataKey, null); //invalidate | ||
//writeout the value | ||
var cv = this.opts.autoUnmask ? unmaskedvalue(this.el) : this._valueGet(this.opts.autoUnmask); | ||
if (cv !== getBufferTemplate.call(this).join("")) this._valueSet(cv, this.opts.autoUnmask); else this._valueSet(""); | ||
//unbind all events | ||
EventRuler.off(this.el); | ||
$.data(el, dataKey, that.userOptions); | ||
mask.call(el.inputmask); | ||
} | ||
} | ||
}); | ||
return elems && elems[0] ? elems[0].inputmask || this : this; | ||
}, | ||
option: function (options, noremask) { | ||
// set extra options || retrieve value of a current option | ||
if (typeof options === "string") { | ||
return this.opts[options]; | ||
} else if (typeof options === "object") { | ||
$.extend(this.userOptions, options); // user passed options | ||
// remask | ||
if (this.el && noremask !== true) { | ||
this.mask(this.el); | ||
} | ||
return this; | ||
} | ||
}, | ||
unmaskedvalue: function (value) { | ||
this.maskset = | ||
this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
if (this.el === undefined || value !== undefined) { | ||
const valueBuffer = ( | ||
typeof this.opts.onBeforeMask === "function" | ||
? this.opts.onBeforeMask.call(this, value, this.opts) || value | ||
: value | ||
).split(""); | ||
checkVal.call(this, undefined, false, false, valueBuffer); | ||
if (typeof this.opts.onBeforeWrite === "function") | ||
this.opts.onBeforeWrite.call( | ||
this, | ||
undefined, | ||
getBuffer.call(this), | ||
0, | ||
this.opts | ||
); | ||
} | ||
return unmaskedvalue.call(this, this.el); | ||
}, | ||
remove: function () { | ||
if (this.el) { | ||
$.data(this.el, dataKey, null); // invalidate | ||
// writeout the value | ||
const cv = this.opts.autoUnmask | ||
? unmaskedvalue(this.el) | ||
: this._valueGet(this.opts.autoUnmask); | ||
if (cv !== getBufferTemplate.call(this).join("")) | ||
this._valueSet(cv, this.opts.autoUnmask); | ||
else this._valueSet(""); | ||
// unbind all events | ||
EventRuler.off(this.el); | ||
//restore the value property | ||
var valueProperty; | ||
if (Object.getOwnPropertyDescriptor && Object.getPrototypeOf) { | ||
valueProperty = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(this.el), "value"); | ||
if (valueProperty) { | ||
if (this.__valueGet) { | ||
Object.defineProperty(this.el, "value", { | ||
get: this.__valueGet, | ||
set: this.__valueSet, | ||
configurable: true | ||
}); | ||
} | ||
} | ||
} else if (document.__lookupGetter__ && this.el.__lookupGetter__("value")) { | ||
if (this.__valueGet) { | ||
this.el.__defineGetter__("value", this.__valueGet); | ||
this.el.__defineSetter__("value", this.__valueSet); | ||
} | ||
} | ||
//clear data | ||
this.el.inputmask = undefined; | ||
} | ||
return this.el; | ||
}, | ||
getemptymask: function () { //return the default (empty) mask value, usefull for setting the default value in validation | ||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
return (this.isRTL ? getBufferTemplate.call(this).reverse() : getBufferTemplate.call(this)).join(""); | ||
}, | ||
hasMaskedValue: function () { //check wheter the returned value is masked or not; currently only works reliable when using jquery.val fn to retrieve the value | ||
return !this.opts.autoUnmask; | ||
}, | ||
isComplete: function () { | ||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
return isComplete.call(this, getBuffer.call(this)); | ||
}, | ||
getmetadata: function () { //return mask metadata if exists | ||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
if (Array.isArray(this.maskset.metadata)) { | ||
var maskTarget = getMaskTemplate.call(this, true, 0, false).join(""); | ||
this.maskset.metadata.forEach(function (mtdt) { | ||
if (mtdt.mask === maskTarget) { | ||
maskTarget = mtdt; | ||
return false; | ||
} | ||
// restore the value property | ||
let valueProperty; | ||
if (Object.getOwnPropertyDescriptor && Object.getPrototypeOf) { | ||
valueProperty = Object.getOwnPropertyDescriptor( | ||
Object.getPrototypeOf(this.el), | ||
"value" | ||
); | ||
if (valueProperty) { | ||
if (this.__valueGet) { | ||
Object.defineProperty(this.el, "value", { | ||
get: this.__valueGet, | ||
set: this.__valueSet, | ||
configurable: true | ||
}); | ||
} | ||
} | ||
} else if ( | ||
document.__lookupGetter__ && | ||
this.el.__lookupGetter__("value") | ||
) { | ||
if (this.__valueGet) { | ||
this.el.__defineGetter__("value", this.__valueGet); | ||
this.el.__defineSetter__("value", this.__valueSet); | ||
} | ||
} | ||
// clear data | ||
this.el.inputmask = undefined; | ||
} | ||
return this.el; | ||
}, | ||
getemptymask: function () { | ||
// return the default (empty) mask value, usefull for setting the default value in validation | ||
this.maskset = | ||
this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
return ( | ||
this.isRTL | ||
? getBufferTemplate.call(this).reverse() | ||
: getBufferTemplate.call(this) | ||
).join(""); | ||
}, | ||
hasMaskedValue: function () { | ||
// check wheter the returned value is masked or not; currently only works reliable when using jquery.val fn to retrieve the value | ||
return !this.opts.autoUnmask; | ||
}, | ||
isComplete: function () { | ||
this.maskset = | ||
this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
return isComplete.call(this, getBuffer.call(this)); | ||
}, | ||
getmetadata: function () { | ||
// return mask metadata if exists | ||
this.maskset = | ||
this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
if (Array.isArray(this.maskset.metadata)) { | ||
let maskTarget = getMaskTemplate.call(this, true, 0, false).join(""); | ||
this.maskset.metadata.forEach(function (mtdt) { | ||
if (mtdt.mask === maskTarget) { | ||
maskTarget = mtdt; | ||
return false; | ||
} | ||
return true; | ||
}); | ||
return maskTarget; | ||
} | ||
return this.maskset.metadata; | ||
}, | ||
isValid: function (value) { | ||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
if (value) { | ||
var valueBuffer = (typeof this.opts.onBeforeMask === "function" ? (this.opts.onBeforeMask.call(this, value, this.opts) || value) : value).split(""); | ||
checkVal.call(this, undefined, true, false, valueBuffer); | ||
} else { | ||
value = this.isRTL ? getBuffer.call(this).slice().reverse().join("") : getBuffer.call(this).join(""); | ||
} | ||
var buffer = getBuffer.call(this); | ||
var rl = determineLastRequiredPosition.call(this), | ||
lmib = buffer.length - 1; | ||
for (; lmib > rl; lmib--) { | ||
if (isMask.call(this, lmib)) break; | ||
} | ||
buffer.splice(rl, lmib + 1 - rl); | ||
return true; | ||
}); | ||
return maskTarget; | ||
} | ||
return this.maskset.metadata; | ||
}, | ||
isValid: function (value) { | ||
this.maskset = | ||
this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
if (value) { | ||
const valueBuffer = ( | ||
typeof this.opts.onBeforeMask === "function" | ||
? this.opts.onBeforeMask.call(this, value, this.opts) || value | ||
: value | ||
).split(""); | ||
checkVal.call(this, undefined, true, false, valueBuffer); | ||
} else { | ||
value = this.isRTL | ||
? getBuffer.call(this).slice().reverse().join("") | ||
: getBuffer.call(this).join(""); | ||
} | ||
let buffer = getBuffer.call(this), | ||
rl = determineLastRequiredPosition.call(this), | ||
lmib = buffer.length - 1; | ||
for (; lmib > rl; lmib--) { | ||
if (isMask.call(this, lmib)) break; | ||
} | ||
buffer.splice(rl, lmib + 1 - rl); | ||
return isComplete.call(this, buffer) && value === (this.isRTL ? getBuffer.call(this).slice().reverse().join("") : getBuffer.call(this).join("")); | ||
}, | ||
format: function (value, metadata) { | ||
this.maskset = this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
let valueBuffer = (typeof this.opts.onBeforeMask === "function" ? (this.opts.onBeforeMask.call(this, value, this.opts) || value) : value).split(""); | ||
checkVal.call(this, undefined, true, false, valueBuffer); | ||
let formattedValue = this.isRTL ? getBuffer.call(this).slice().reverse().join("") : getBuffer.call(this).join(""); | ||
return metadata ? { | ||
value: formattedValue, | ||
metadata: this.getmetadata() | ||
} : formattedValue; | ||
}, | ||
setValue: function (value) { | ||
if (this.el) { | ||
$(this.el).trigger("setvalue", [value]); | ||
} | ||
}, | ||
analyseMask: analyseMask | ||
return ( | ||
isComplete.call(this, buffer) && | ||
value === | ||
(this.isRTL | ||
? getBuffer.call(this).slice().reverse().join("") | ||
: getBuffer.call(this).join("")) | ||
); | ||
}, | ||
format: function (value, metadata) { | ||
this.maskset = | ||
this.maskset || generateMaskSet(this.opts, this.noMasksCache); | ||
const valueBuffer = ( | ||
typeof this.opts.onBeforeMask === "function" | ||
? this.opts.onBeforeMask.call(this, value, this.opts) || value | ||
: value | ||
).split(""); | ||
checkVal.call(this, undefined, true, false, valueBuffer); | ||
const formattedValue = this.isRTL | ||
? getBuffer.call(this).slice().reverse().join("") | ||
: getBuffer.call(this).join(""); | ||
return metadata | ||
? { | ||
value: formattedValue, | ||
metadata: this.getmetadata() | ||
} | ||
: formattedValue; | ||
}, | ||
setValue: function (value) { | ||
if (this.el) { | ||
$(this.el).trigger("setvalue", [value]); | ||
} | ||
}, | ||
analyseMask | ||
}; | ||
function resolveAlias(aliasStr, options, opts) { | ||
var aliasDefinition = Inputmask.prototype.aliases[aliasStr]; | ||
if (aliasDefinition) { | ||
if (aliasDefinition.alias) resolveAlias(aliasDefinition.alias, undefined, opts); //alias is another alias | ||
$.extend(true, opts, aliasDefinition); //merge alias definition in the options | ||
$.extend(true, opts, options); //reapply extra given options | ||
return true; | ||
} else //alias not found - try as mask | ||
if (opts.mask === null) { | ||
opts.mask = aliasStr; | ||
} | ||
const aliasDefinition = Inputmask.prototype.aliases[aliasStr]; | ||
if (aliasDefinition) { | ||
if (aliasDefinition.alias) | ||
resolveAlias(aliasDefinition.alias, undefined, opts); // alias is another alias | ||
$.extend(true, opts, aliasDefinition); // merge alias definition in the options | ||
$.extend(true, opts, options); // reapply extra given options | ||
return true; | ||
} // alias not found - try as mask | ||
else if (opts.mask === null) { | ||
opts.mask = aliasStr; | ||
} | ||
return false; | ||
return false; | ||
} | ||
function importAttributeOptions(npt, opts, userOptions, dataAttribute) { | ||
function importOption(option, optionData) { | ||
const attrOption = dataAttribute === "" ? option : dataAttribute + "-" + option; | ||
optionData = optionData !== undefined ? optionData : npt.getAttribute(attrOption); | ||
if (optionData !== null) { | ||
if (typeof optionData === "string") { | ||
if (option.indexOf("on") === 0) { | ||
optionData = window[optionData]; | ||
}//get function definition | ||
else if (optionData === "false") { | ||
optionData = false; | ||
} else if (optionData === "true") optionData = true; | ||
} | ||
userOptions[option] = optionData; | ||
} | ||
} | ||
function importOption(option, optionData) { | ||
const attrOption = | ||
dataAttribute === "" ? option : dataAttribute + "-" + option; | ||
optionData = | ||
optionData !== undefined ? optionData : npt.getAttribute(attrOption); | ||
if (optionData !== null) { | ||
if (typeof optionData === "string") { | ||
if (option.indexOf("on") === 0) { | ||
optionData = window[optionData]; | ||
} // get function definition | ||
else if (optionData === "false") { | ||
optionData = false; | ||
} else if (optionData === "true") optionData = true; | ||
} | ||
userOptions[option] = optionData; | ||
} | ||
} | ||
if (opts.importDataAttributes === true) { | ||
var attrOptions = npt.getAttribute(dataAttribute), option, dataoptions, optionData, p; | ||
if (opts.importDataAttributes === true) { | ||
let attrOptions = npt.getAttribute(dataAttribute), | ||
option, | ||
dataoptions, | ||
optionData, | ||
p; | ||
if (attrOptions && attrOptions !== "") { | ||
attrOptions = attrOptions.replace(/'/g, "\""); | ||
dataoptions = JSON.parse("{" + attrOptions + "}"); | ||
} | ||
if (attrOptions && attrOptions !== "") { | ||
attrOptions = attrOptions.replace(/'/g, '"'); | ||
dataoptions = JSON.parse("{" + attrOptions + "}"); | ||
} | ||
//resolve aliases | ||
if (dataoptions) { //pickup alias from dataAttribute | ||
optionData = undefined; | ||
for (p in dataoptions) { | ||
if (p.toLowerCase() === "alias") { | ||
optionData = dataoptions[p]; | ||
break; | ||
} | ||
} | ||
} | ||
importOption("alias", optionData); //pickup alias from dataAttribute-alias | ||
if (userOptions.alias) { | ||
resolveAlias(userOptions.alias, userOptions, opts); | ||
} | ||
// resolve aliases | ||
if (dataoptions) { | ||
// pickup alias from dataAttribute | ||
optionData = undefined; | ||
for (p in dataoptions) { | ||
if (p.toLowerCase() === "alias") { | ||
optionData = dataoptions[p]; | ||
break; | ||
} | ||
} | ||
} | ||
importOption("alias", optionData); // pickup alias from dataAttribute-alias | ||
if (userOptions.alias) { | ||
resolveAlias(userOptions.alias, userOptions, opts); | ||
} | ||
for (option in opts) { | ||
if (dataoptions) { | ||
optionData = undefined; | ||
for (p in dataoptions) { | ||
if (p.toLowerCase() === option.toLowerCase()) { | ||
optionData = dataoptions[p]; | ||
break; | ||
} | ||
} | ||
} | ||
importOption(option, optionData); | ||
} | ||
} | ||
$.extend(true, opts, userOptions); | ||
for (option in opts) { | ||
if (dataoptions) { | ||
optionData = undefined; | ||
for (p in dataoptions) { | ||
if (p.toLowerCase() === option.toLowerCase()) { | ||
optionData = dataoptions[p]; | ||
break; | ||
} | ||
} | ||
} | ||
importOption(option, optionData); | ||
} | ||
} | ||
$.extend(true, opts, userOptions); | ||
//handle dir=rtl | ||
if (npt.dir === "rtl" || opts.rightAlign) { | ||
npt.style.textAlign = "right"; | ||
} | ||
// handle dir=rtl | ||
if (npt.dir === "rtl" || opts.rightAlign) { | ||
npt.style.textAlign = "right"; | ||
} | ||
if (npt.dir === "rtl" || opts.numericInput) { | ||
npt.dir = "ltr"; | ||
npt.removeAttribute("dir"); | ||
opts.isRTL = true; | ||
} | ||
if (npt.dir === "rtl" || opts.numericInput) { | ||
npt.dir = "ltr"; | ||
npt.removeAttribute("dir"); | ||
opts.isRTL = true; | ||
} | ||
return Object.keys(userOptions).length; | ||
return Object.keys(userOptions).length; | ||
} | ||
//apply defaults, definitions, aliases | ||
// apply defaults, definitions, aliases | ||
Inputmask.extendDefaults = function (options) { | ||
$.extend(true, Inputmask.prototype.defaults, options); | ||
$.extend(true, Inputmask.prototype.defaults, options); | ||
}; | ||
Inputmask.extendDefinitions = function (definition) { | ||
$.extend(true, Inputmask.prototype.definitions, definition); | ||
$.extend(true, Inputmask.prototype.definitions, definition); | ||
}; | ||
Inputmask.extendAliases = function (alias) { | ||
$.extend(true, Inputmask.prototype.aliases, alias); | ||
$.extend(true, Inputmask.prototype.aliases, alias); | ||
}; | ||
//static fn on inputmask | ||
// static fn on inputmask | ||
Inputmask.format = function (value, options, metadata) { | ||
return Inputmask(options).format(value, metadata); | ||
return Inputmask(options).format(value, metadata); | ||
}; | ||
Inputmask.unmask = function (value, options) { | ||
return Inputmask(options).unmaskedvalue(value); | ||
return Inputmask(options).unmaskedvalue(value); | ||
}; | ||
Inputmask.isValid = function (value, options) { | ||
return Inputmask(options).isValid(value); | ||
return Inputmask(options).isValid(value); | ||
}; | ||
Inputmask.remove = function (elems) { | ||
if (typeof elems === "string") { | ||
elems = document.getElementById(elems) || document.querySelectorAll(elems); | ||
} | ||
elems = elems.nodeName ? [elems] : elems; | ||
elems.forEach(function (el) { | ||
if (el.inputmask) el.inputmask.remove(); | ||
}); | ||
if (typeof elems === "string") { | ||
elems = document.getElementById(elems) || document.querySelectorAll(elems); | ||
} | ||
elems = elems.nodeName ? [elems] : elems; | ||
elems.forEach(function (el) { | ||
if (el.inputmask) el.inputmask.remove(); | ||
}); | ||
}; | ||
Inputmask.setValue = function (elems, value) { | ||
if (typeof elems === "string") { | ||
elems = document.getElementById(elems) || document.querySelectorAll(elems); | ||
} | ||
elems = elems.nodeName ? [elems] : elems; | ||
elems.forEach(function (el) { | ||
if (el.inputmask) el.inputmask.setValue(value); else $(el).trigger("setvalue", [value]); | ||
}); | ||
if (typeof elems === "string") { | ||
elems = document.getElementById(elems) || document.querySelectorAll(elems); | ||
} | ||
elems = elems.nodeName ? [elems] : elems; | ||
elems.forEach(function (el) { | ||
if (el.inputmask) el.inputmask.setValue(value); | ||
else $(el).trigger("setvalue", [value]); | ||
}); | ||
}; | ||
@@ -349,4 +431,4 @@ | ||
//make inputmask available | ||
// make inputmask available | ||
window.Inputmask = Inputmask; | ||
export default Inputmask; |
@@ -8,38 +8,48 @@ import window from "./global/window"; | ||
// integrate shadowroot into maskcope | ||
if (document && document.head && document.head.attachShadow && window.customElements && window.customElements.get("input-mask") === undefined) { | ||
class InputmaskElement extends HTMLElement { | ||
constructor() { | ||
super(); | ||
var attributeNames = this.getAttributeNames(), | ||
shadow = this.attachShadow({mode: "closed"}); | ||
this.input = document.createElement("input"); | ||
this.input.type = "text"; | ||
shadow.appendChild(this.input); | ||
if ( | ||
document && | ||
document.head && | ||
document.head.attachShadow && | ||
window.customElements && | ||
window.customElements.get("input-mask") === undefined | ||
) { | ||
class InputmaskElement extends HTMLElement { | ||
constructor() { | ||
super(); | ||
const attributeNames = this.getAttributeNames(), | ||
shadow = this.attachShadow({ mode: "closed" }); | ||
this.input = document.createElement("input"); | ||
this.input.type = "text"; | ||
shadow.appendChild(this.input); | ||
for (var attr in attributeNames) { | ||
if (Object.prototype.hasOwnProperty.call(attributeNames, attr)) { | ||
this.input.setAttribute(attributeNames[attr], this.getAttribute(attributeNames[attr])); | ||
} | ||
} | ||
for (const attr in attributeNames) { | ||
if (Object.prototype.hasOwnProperty.call(attributeNames, attr)) { | ||
this.input.setAttribute( | ||
attributeNames[attr], | ||
this.getAttribute(attributeNames[attr]) | ||
); | ||
} | ||
} | ||
var im = new Inputmask(); | ||
im.dataAttribute = ""; | ||
im.mask(this.input); | ||
this.input.inputmask.shadowRoot = shadow; //make the shadowRoot available | ||
} | ||
const im = new Inputmask(); | ||
im.dataAttribute = ""; | ||
im.mask(this.input); | ||
this.input.inputmask.shadowRoot = shadow; // make the shadowRoot available | ||
} | ||
attributeChangedCallback(attrName, oldVal, newVal) { | ||
this.input.setAttribute(attrName, newVal); | ||
} | ||
attributeChangedCallback(attrName, oldVal, newVal) { | ||
this.input.setAttribute(attrName, newVal); | ||
} | ||
//bind value | ||
get value() { | ||
return this.input.value; | ||
} | ||
set value(value) { | ||
this.input.value = value; | ||
} | ||
} | ||
// bind value | ||
get value() { | ||
return this.input.value; | ||
} | ||
window.customElements.define("input-mask", InputmaskElement); | ||
set value(value) { | ||
this.input.value = value; | ||
} | ||
} | ||
window.customElements.define("input-mask", InputmaskElement); | ||
} |
@@ -8,75 +8,83 @@ /* | ||
import $ from "jquery"; | ||
import Inputmask from "./inputmask"; | ||
if ($.fn.inputmask === undefined) { | ||
//jquery plugin | ||
$.fn.inputmask = function (fn, options) { | ||
var nptmask, input = this[0]; | ||
if (options === undefined) options = {}; | ||
if (typeof fn === "string") { | ||
switch (fn) { | ||
case "unmaskedvalue": | ||
return input && input.inputmask ? input.inputmask.unmaskedvalue() : $(input).val(); | ||
case "remove": | ||
return this.each(function () { | ||
if (this.inputmask) this.inputmask.remove(); | ||
}); | ||
case "getemptymask": | ||
return input && input.inputmask ? input.inputmask.getemptymask() : ""; | ||
case "hasMaskedValue": //check whether the returned value is masked or not; currently only works reliable when using jquery.val fn to retrieve the value | ||
return input && input.inputmask ? input.inputmask.hasMaskedValue() : false; | ||
case "isComplete": | ||
return input && input.inputmask ? input.inputmask.isComplete() : true; | ||
case "getmetadata": //return mask metadata if exists | ||
return input && input.inputmask ? input.inputmask.getmetadata() : undefined; | ||
case "setvalue": | ||
Inputmask.setValue(input, options); | ||
break; | ||
case "option": | ||
if (typeof options === "string") { | ||
if (input && input.inputmask !== undefined) { | ||
return input.inputmask.option(options); | ||
} | ||
} else { | ||
return this.each(function () { | ||
if (this.inputmask !== undefined) { | ||
return this.inputmask.option(options); | ||
} | ||
}); | ||
} | ||
break; | ||
default: | ||
options.alias = fn; | ||
nptmask = new Inputmask(options); | ||
return this.each(function () { | ||
nptmask.mask(this); | ||
}); | ||
} | ||
} else if (Array.isArray(fn)) { | ||
options.alias = fn; | ||
nptmask = new Inputmask(options); | ||
return this.each(function () { | ||
nptmask.mask(this); | ||
}); | ||
} else if (typeof fn == "object") { | ||
nptmask = new Inputmask(fn); | ||
if (fn.mask === undefined && fn.alias === undefined) { | ||
return this.each(function () { | ||
if (this.inputmask !== undefined) { | ||
return this.inputmask.option(fn); | ||
} else nptmask.mask(this); | ||
}); | ||
} else { | ||
return this.each(function () { | ||
nptmask.mask(this); | ||
}); | ||
} | ||
} else if (fn === undefined) { | ||
//look for data-inputmask atributes | ||
return this.each(function () { | ||
nptmask = new Inputmask(options); | ||
nptmask.mask(this); | ||
}); | ||
} | ||
}; | ||
// jquery plugin | ||
$.fn.inputmask = function (fn, options) { | ||
let nptmask, | ||
input = this[0]; | ||
if (options === undefined) options = {}; | ||
if (typeof fn === "string") { | ||
switch (fn) { | ||
case "unmaskedvalue": | ||
return input && input.inputmask | ||
? input.inputmask.unmaskedvalue() | ||
: $(input).val(); | ||
case "remove": | ||
return this.each(function () { | ||
if (this.inputmask) this.inputmask.remove(); | ||
}); | ||
case "getemptymask": | ||
return input && input.inputmask ? input.inputmask.getemptymask() : ""; | ||
case "hasMaskedValue": // check whether the returned value is masked or not; currently only works reliable when using jquery.val fn to retrieve the value | ||
return input && input.inputmask | ||
? input.inputmask.hasMaskedValue() | ||
: false; | ||
case "isComplete": | ||
return input && input.inputmask ? input.inputmask.isComplete() : true; | ||
case "getmetadata": // return mask metadata if exists | ||
return input && input.inputmask | ||
? input.inputmask.getmetadata() | ||
: undefined; | ||
case "setvalue": | ||
Inputmask.setValue(input, options); | ||
break; | ||
case "option": | ||
if (typeof options === "string") { | ||
if (input && input.inputmask !== undefined) { | ||
return input.inputmask.option(options); | ||
} | ||
} else { | ||
return this.each(function () { | ||
if (this.inputmask !== undefined) { | ||
return this.inputmask.option(options); | ||
} | ||
}); | ||
} | ||
break; | ||
default: | ||
options.alias = fn; | ||
nptmask = new Inputmask(options); | ||
return this.each(function () { | ||
nptmask.mask(this); | ||
}); | ||
} | ||
} else if (Array.isArray(fn)) { | ||
options.alias = fn; | ||
nptmask = new Inputmask(options); | ||
return this.each(function () { | ||
nptmask.mask(this); | ||
}); | ||
} else if (typeof fn === "object") { | ||
nptmask = new Inputmask(fn); | ||
if (fn.mask === undefined && fn.alias === undefined) { | ||
return this.each(function () { | ||
if (this.inputmask !== undefined) { | ||
return this.inputmask.option(fn); | ||
} else nptmask.mask(this); | ||
}); | ||
} else { | ||
return this.each(function () { | ||
nptmask.mask(this); | ||
}); | ||
} | ||
} else if (fn === undefined) { | ||
// look for data-inputmask atributes | ||
return this.each(function () { | ||
nptmask = new Inputmask(options); | ||
nptmask.mask(this); | ||
}); | ||
} | ||
}; | ||
} |
@@ -1,65 +0,81 @@ | ||
export {keyCode, toKey, toKeyCode, keys}; | ||
export { keyCode, toKey, toKeyCode, keys }; | ||
const ignorables = { | ||
"Alt": 18, | ||
"AltGraph": 18, | ||
"ArrowDown": 40, | ||
"ArrowLeft": 37, | ||
"ArrowRight": 39, | ||
"ArrowUp": 38, | ||
"Backspace": 8, | ||
"CapsLock": 20, | ||
"Control": 17, | ||
"ContextMenu": 93, | ||
"Dead": 221, | ||
"Delete": 46, | ||
"End": 35, | ||
"Escape": 27, | ||
"F1": 112, | ||
"F2": 113, | ||
"F3": 114, | ||
"F4": 115, | ||
"F5": 116, | ||
"F6": 117, | ||
"F7": 118, | ||
"F8": 119, | ||
"F9": 120, | ||
"F10": 121, | ||
"F11": 122, | ||
"F12": 123, | ||
"Home": 36, | ||
"Insert": 45, | ||
"NumLock": 144, | ||
"PageDown": 34, | ||
"PageUp": 33, | ||
"Pause": 19, | ||
"PrintScreen": 44, | ||
"Process": 229, | ||
"Shift": 16, | ||
"ScrollLock": 145, | ||
"Tab": 9, | ||
"Unidentified": 229, | ||
Alt: 18, | ||
AltGraph: 18, | ||
ArrowDown: 40, | ||
ArrowLeft: 37, | ||
ArrowRight: 39, | ||
ArrowUp: 38, | ||
Backspace: 8, | ||
CapsLock: 20, | ||
Control: 17, | ||
ContextMenu: 93, | ||
Dead: 221, | ||
Delete: 46, | ||
End: 35, | ||
Escape: 27, | ||
F1: 112, | ||
F2: 113, | ||
F3: 114, | ||
F4: 115, | ||
F5: 116, | ||
F6: 117, | ||
F7: 118, | ||
F8: 119, | ||
F9: 120, | ||
F10: 121, | ||
F11: 122, | ||
F12: 123, | ||
Home: 36, | ||
Insert: 45, | ||
NumLock: 144, | ||
PageDown: 34, | ||
PageUp: 33, | ||
Pause: 19, | ||
PrintScreen: 44, | ||
Process: 229, | ||
Shift: 16, | ||
ScrollLock: 145, | ||
Tab: 9, | ||
Unidentified: 229 | ||
}; | ||
var keyCode = { | ||
"c": 67, | ||
"x": 88, | ||
"z": 90, | ||
"BACKSPACE_SAFARI": 127, | ||
"Enter": 13, | ||
"Meta_LEFT": 91, | ||
"Meta_RIGHT": 92, | ||
"Space": 32, | ||
...ignorables | ||
} | ||
c: 67, | ||
x: 88, | ||
z: 90, | ||
BACKSPACE_SAFARI: 127, | ||
Enter: 13, | ||
Meta_LEFT: 91, | ||
Meta_RIGHT: 92, | ||
Space: 32, | ||
...ignorables | ||
}; | ||
const keyCodeRev = Object.entries(keyCode).reduce((acc, [key, value]) => (acc[value] = acc[value] === undefined ? key : acc[value] , acc), {}); | ||
const keys = Object.entries(keyCode).reduce((acc, [key, value]) => (acc[key] = key === "Space" ? " " : key, acc), {}); | ||
const keyCodeRev = Object.entries(keyCode).reduce( | ||
(acc, [key, value]) => | ||
( | ||
// eslint-disable-next-line no-sequences | ||
(acc[value] = acc[value] === undefined ? key : acc[value]), acc | ||
), | ||
{} | ||
), | ||
keys = Object.entries(keyCode).reduce( | ||
// eslint-disable-next-line no-sequences | ||
(acc, [key, value]) => ((acc[key] = key === "Space" ? " " : key), acc), | ||
{} | ||
); | ||
function toKey(keyCode, shiftKey) { | ||
return keyCodeRev[keyCode] || (shiftKey ? String.fromCharCode(keyCode) : String.fromCharCode(keyCode).toLowerCase()); | ||
return ( | ||
keyCodeRev[keyCode] || | ||
(shiftKey | ||
? String.fromCharCode(keyCode) | ||
: String.fromCharCode(keyCode).toLowerCase()) | ||
); | ||
} | ||
function toKeyCode(key) { | ||
return keyCode[key]; | ||
return keyCode[key]; | ||
} |
import $ from "./dependencyLibs/inputmask.dependencyLib"; | ||
import escapeRegex from "./escapeRegex"; | ||
import Inputmask from "./inputmask"; | ||
import MaskToken from "./masktoken"; | ||
import Inputmask from "./inputmask"; | ||
import escapeRegex from "./escapeRegex"; | ||
export {generateMaskSet, analyseMask}; | ||
export { generateMaskSet, analyseMask }; | ||
function generateMaskSet(opts, nocache) { | ||
var ms; | ||
let ms; | ||
function preProcessMask(mask, {repeat, groupmarker, quantifiermarker, keepStatic}) { | ||
if (repeat > 0 || repeat === "*" || repeat === "+") { | ||
var repeatStart = repeat === "*" ? 0 : (repeat === "+" ? 1 : repeat); | ||
if (repeatStart != repeat) { | ||
mask = groupmarker[0] + mask + groupmarker[1] + quantifiermarker[0] + repeatStart + "," + repeat + quantifiermarker[1]; | ||
} else { | ||
// repeat the mask n times | ||
var msk = mask; | ||
for (let i = 1; i < repeatStart; i++) { | ||
mask += msk; | ||
} | ||
} | ||
} | ||
if (keepStatic === true) { | ||
let optionalRegex = "(.)\\[([^\\]]*)\\]", // "(?<p1>.)\\[(?<p2>[^\\]]*)\\]", remove named capture group @2428 | ||
maskMatches = mask.match(new RegExp(optionalRegex, "g")); | ||
maskMatches && maskMatches.forEach((m, i) => { | ||
let [p1, p2] = m.split("["); | ||
p2 = p2.replace("]", ""); | ||
mask = mask.replace(new RegExp(`${escapeRegex(p1)}\\[${escapeRegex(p2)}\\]`), | ||
p1.charAt(0) === p2.charAt(0) ? | ||
`(${p1}|${p1}${p2})` : | ||
`${p1}[${p2}]`); | ||
// console.log(mask); | ||
}); | ||
} | ||
function preProcessMask( | ||
mask, | ||
{ repeat, groupmarker, quantifiermarker, keepStatic } | ||
) { | ||
if (repeat > 0 || repeat === "*" || repeat === "+") { | ||
const repeatStart = repeat === "*" ? 0 : repeat === "+" ? 1 : repeat; | ||
if (repeatStart != repeat) { | ||
mask = | ||
groupmarker[0] + | ||
mask + | ||
groupmarker[1] + | ||
quantifiermarker[0] + | ||
repeatStart + | ||
"," + | ||
repeat + | ||
quantifiermarker[1]; | ||
} else { | ||
// repeat the mask n times | ||
const msk = mask; | ||
for (let i = 1; i < repeatStart; i++) { | ||
mask += msk; | ||
} | ||
} | ||
} | ||
if (keepStatic === true) { | ||
const optionalRegex = "(.)\\[([^\\]]*)\\]", // "(?<p1>.)\\[(?<p2>[^\\]]*)\\]", remove named capture group @2428 | ||
maskMatches = mask.match(new RegExp(optionalRegex, "g")); | ||
maskMatches && | ||
maskMatches.forEach((m, i) => { | ||
let [p1, p2] = m.split("["); | ||
p2 = p2.replace("]", ""); | ||
mask = mask.replace( | ||
new RegExp(`${escapeRegex(p1)}\\[${escapeRegex(p2)}\\]`), | ||
p1.charAt(0) === p2.charAt(0) | ||
? `(${p1}|${p1}${p2})` | ||
: `${p1}[${p2}]` | ||
); | ||
// console.log(mask); | ||
}); | ||
} | ||
return mask; | ||
} | ||
return mask; | ||
} | ||
function generateMask(mask, metadata, opts) { | ||
var regexMask = false; | ||
if (mask === null || mask === "") { | ||
regexMask = opts.regex !== null; | ||
if (regexMask) { | ||
mask = opts.regex; | ||
mask = mask.replace(/^(\^)(.*)(\$)$/, "$2"); | ||
} else { | ||
regexMask = true; | ||
mask = ".*"; | ||
} | ||
} | ||
if (mask.length === 1 && opts.greedy === false && opts.repeat !== 0) { | ||
opts.placeholder = ""; | ||
} //hide placeholder with single non-greedy mask | ||
mask = preProcessMask(mask, opts); | ||
function generateMask(mask, metadata, opts) { | ||
let regexMask = false; | ||
if (mask === null || mask === "") { | ||
regexMask = opts.regex !== null; | ||
if (regexMask) { | ||
mask = opts.regex; | ||
mask = mask.replace(/^(\^)(.*)(\$)$/, "$2"); | ||
} else { | ||
regexMask = true; | ||
mask = ".*"; | ||
} | ||
} | ||
if (mask.length === 1 && opts.greedy === false && opts.repeat !== 0) { | ||
opts.placeholder = ""; | ||
} // hide placeholder with single non-greedy mask | ||
mask = preProcessMask(mask, opts); | ||
// console.log(mask); | ||
var masksetDefinition, maskdefKey; | ||
maskdefKey = regexMask ? "regex_" + opts.regex : opts.numericInput ? mask.split("").reverse().join("") : mask; | ||
if (opts.keepStatic !== null) { //keepstatic modifies the output from the testdefinitions ~ so differentiate in the maskcache | ||
maskdefKey = "ks_" + opts.keepStatic + maskdefKey; | ||
} | ||
if (typeof opts.placeholder === "object") { //placeholder object modifies the output from the testdefinitions ~ so differentiate in the maskcache | ||
maskdefKey = "ph_" + JSON.stringify(opts.placeholder) + maskdefKey; | ||
} | ||
// console.log(mask); | ||
let masksetDefinition, maskdefKey; | ||
maskdefKey = regexMask | ||
? "regex_" + opts.regex | ||
: opts.numericInput | ||
? mask.split("").reverse().join("") | ||
: mask; | ||
if (opts.keepStatic !== null) { | ||
// keepstatic modifies the output from the testdefinitions ~ so differentiate in the maskcache | ||
maskdefKey = "ks_" + opts.keepStatic + maskdefKey; | ||
} | ||
if (typeof opts.placeholder === "object") { | ||
// placeholder object modifies the output from the testdefinitions ~ so differentiate in the maskcache | ||
maskdefKey = "ph_" + JSON.stringify(opts.placeholder) + maskdefKey; | ||
} | ||
if (Inputmask.prototype.masksCache[maskdefKey] === undefined || nocache === true) { | ||
masksetDefinition = { | ||
"mask": mask, | ||
"maskToken": Inputmask.prototype.analyseMask(mask, regexMask, opts), | ||
"validPositions": [], | ||
"_buffer": undefined, | ||
"buffer": undefined, | ||
"tests": {}, | ||
"excludes": {}, //excluded alternations | ||
"metadata": metadata, | ||
"maskLength": undefined, | ||
"jitOffset": {} | ||
}; | ||
if (nocache !== true) { | ||
Inputmask.prototype.masksCache[maskdefKey] = masksetDefinition; | ||
masksetDefinition = $.extend(true, {}, Inputmask.prototype.masksCache[maskdefKey]); | ||
} | ||
} else { | ||
masksetDefinition = $.extend(true, {}, Inputmask.prototype.masksCache[maskdefKey]); | ||
} | ||
if ( | ||
Inputmask.prototype.masksCache[maskdefKey] === undefined || | ||
nocache === true | ||
) { | ||
masksetDefinition = { | ||
mask, | ||
maskToken: Inputmask.prototype.analyseMask(mask, regexMask, opts), | ||
validPositions: [], | ||
_buffer: undefined, | ||
buffer: undefined, | ||
tests: {}, | ||
excludes: {}, // excluded alternations | ||
metadata, | ||
maskLength: undefined, | ||
jitOffset: {} | ||
}; | ||
if (nocache !== true) { | ||
Inputmask.prototype.masksCache[maskdefKey] = masksetDefinition; | ||
masksetDefinition = $.extend( | ||
true, | ||
{}, | ||
Inputmask.prototype.masksCache[maskdefKey] | ||
); | ||
} | ||
} else { | ||
masksetDefinition = $.extend( | ||
true, | ||
{}, | ||
Inputmask.prototype.masksCache[maskdefKey] | ||
); | ||
} | ||
return masksetDefinition; | ||
} | ||
return masksetDefinition; | ||
} | ||
if (typeof opts.mask === "function") { //allow mask to be a preprocessing fn - should return a valid mask | ||
opts.mask = opts.mask(opts); | ||
} | ||
if (Array.isArray(opts.mask)) { | ||
if (opts.mask.length > 1) { | ||
if (opts.keepStatic === null) { //enable by default when passing multiple masks when the option is not explicitly specified | ||
opts.keepStatic = true; | ||
} | ||
var altMask = opts.groupmarker[0]; | ||
(opts.isRTL ? opts.mask.reverse() : opts.mask).forEach(function (msk) { | ||
if (altMask.length > 1) { | ||
altMask += opts.alternatormarker; | ||
} | ||
if (msk.mask !== undefined && typeof msk.mask !== "function") { | ||
altMask += msk.mask; | ||
} else { | ||
altMask += msk; | ||
} | ||
}); | ||
altMask += opts.groupmarker[1]; | ||
// console.log(altMask); | ||
return generateMask(altMask, opts.mask, opts); | ||
} else { | ||
opts.mask = opts.mask.pop(); | ||
} | ||
} | ||
if (opts.mask && opts.mask.mask !== undefined && typeof opts.mask.mask !== "function") { | ||
ms = generateMask(opts.mask.mask, opts.mask, opts); | ||
} else { | ||
ms = generateMask(opts.mask, opts.mask, opts); | ||
} | ||
if (opts.keepStatic === null) opts.keepStatic = false; | ||
return ms; | ||
if (typeof opts.mask === "function") { | ||
// allow mask to be a preprocessing fn - should return a valid mask | ||
opts.mask = opts.mask(opts); | ||
} | ||
if (Array.isArray(opts.mask)) { | ||
if (opts.mask.length > 1) { | ||
if (opts.keepStatic === null) { | ||
// enable by default when passing multiple masks when the option is not explicitly specified | ||
opts.keepStatic = true; | ||
} | ||
let altMask = opts.groupmarker[0]; | ||
(opts.isRTL ? opts.mask.reverse() : opts.mask).forEach(function (msk) { | ||
if (altMask.length > 1) { | ||
altMask += opts.alternatormarker; | ||
} | ||
if (msk.mask !== undefined && typeof msk.mask !== "function") { | ||
altMask += msk.mask; | ||
} else { | ||
altMask += msk; | ||
} | ||
}); | ||
altMask += opts.groupmarker[1]; | ||
// console.log(altMask); | ||
return generateMask(altMask, opts.mask, opts); | ||
} else { | ||
opts.mask = opts.mask.pop(); | ||
} | ||
} | ||
if ( | ||
opts.mask && | ||
opts.mask.mask !== undefined && | ||
typeof opts.mask.mask !== "function" | ||
) { | ||
ms = generateMask(opts.mask.mask, opts.mask, opts); | ||
} else { | ||
ms = generateMask(opts.mask, opts.mask, opts); | ||
} | ||
if (opts.keepStatic === null) opts.keepStatic = false; | ||
return ms; | ||
} | ||
function analyseMask(mask, regexMask, opts) { | ||
const tokenizer = /(?:[?*+]|\{[0-9+*]+(?:,[0-9+*]*)?(?:\|[0-9+*]*)?\})|[^.?*+^${[]()|\\]+|./g, | ||
//Thx to https://github.com/slevithan/regex-colorizer for the regexTokenizer regex | ||
regexTokenizer = /\[\^?]?(?:[^\\\]]+|\\[\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; | ||
var escaped = false, | ||
currentToken = new MaskToken(), | ||
match, | ||
m, | ||
openenings = [], | ||
maskTokens = [], | ||
openingToken, | ||
currentOpeningToken, | ||
alternator, | ||
lastMatch, | ||
closeRegexGroup = false; | ||
const tokenizer = | ||
/(?:[?*+]|\{[0-9+*]+(?:,[0-9+*]*)?(?:\|[0-9+*]*)?\})|[^.?*+^${[]()|\\]+|./g, | ||
// Thx to https://github.com/slevithan/regex-colorizer for the regexTokenizer regex | ||
regexTokenizer = | ||
/\[\^?]?(?:[^\\\]]+|\\[\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; | ||
let escaped = false, | ||
currentToken = new MaskToken(), | ||
match, | ||
m, | ||
openenings = [], | ||
maskTokens = [], | ||
openingToken, | ||
currentOpeningToken, | ||
alternator, | ||
lastMatch, | ||
closeRegexGroup = false; | ||
//test definition => {fn: RegExp/function, static: true/false optionality: bool, newBlockMarker: bool, casing: null/upper/lower, def: definitionSymbol, placeholder: placeholder, mask: real maskDefinition} | ||
function insertTestDefinition(mtoken, element, position) { | ||
position = position !== undefined ? position : mtoken.matches.length; | ||
// console.log(element, position, currentToken.matches.length); | ||
// if (typeof opts.placeholder === "string") | ||
// console.log(opts.placeholder.charAt(currentToken.matches.length % opts.placeholder.length)); | ||
var prevMatch = mtoken.matches[position - 1]; | ||
if (regexMask) { | ||
if (element.indexOf("[") === 0 || (escaped && /\\d|\\s|\\w|\\p/i.test(element)) || element === ".") { | ||
let flag = opts.casing ? "i" : ""; | ||
if (/\\p\{.*}/i.test(element)) | ||
flag += "u"; | ||
mtoken.matches.splice(position++, 0, { | ||
fn: new RegExp(element, flag), | ||
static: false, | ||
optionality: false, | ||
newBlockMarker: prevMatch === undefined ? "master" : prevMatch.def !== element, | ||
casing: null, | ||
def: element, | ||
placeholder: typeof opts.placeholder === "object" ? opts.placeholder[currentToken.matches.length] : undefined, | ||
nativeDef: element | ||
}); | ||
} else { | ||
if (escaped) element = element[element.length - 1]; | ||
element.split("").forEach(function (lmnt, ndx) { | ||
prevMatch = mtoken.matches[position - 1]; | ||
mtoken.matches.splice(position++, 0, { | ||
fn: /[a-z]/i.test((opts.staticDefinitionSymbol || lmnt)) ? new RegExp("[" + (opts.staticDefinitionSymbol || lmnt) + "]", opts.casing ? "i" : "") : null, | ||
static: true, | ||
optionality: false, | ||
newBlockMarker: prevMatch === undefined ? "master" : (prevMatch.def !== lmnt && prevMatch.static !== true), | ||
casing: null, | ||
def: opts.staticDefinitionSymbol || lmnt, | ||
placeholder: opts.staticDefinitionSymbol !== undefined ? lmnt : typeof opts.placeholder === "object" ? opts.placeholder[currentToken.matches.length] : undefined, | ||
nativeDef: (escaped ? "'" : "") + lmnt | ||
}); | ||
}); | ||
} | ||
escaped = false; | ||
} else { | ||
var maskdef = (opts.definitions && opts.definitions[element]) || (opts.usePrototypeDefinitions && Inputmask.prototype.definitions[element]); | ||
if (maskdef && !escaped) { | ||
mtoken.matches.splice(position++, 0, { | ||
fn: maskdef.validator ? typeof maskdef.validator == "string" ? new RegExp(maskdef.validator, opts.casing ? "i" : "") : new function () { | ||
this.test = maskdef.validator; | ||
} : new RegExp("."), | ||
static: maskdef.static || false, | ||
optionality: maskdef.optional || false, | ||
defOptionality: maskdef.optional || false, //indicator for an optional from the definition | ||
newBlockMarker: (prevMatch === undefined || maskdef.optional) ? "master" : prevMatch.def !== (maskdef.definitionSymbol || element), | ||
casing: maskdef.casing, | ||
def: maskdef.definitionSymbol || element, | ||
placeholder: maskdef.placeholder, | ||
nativeDef: element, | ||
generated: maskdef.generated | ||
}); | ||
} else { | ||
mtoken.matches.splice(position++, 0, { | ||
fn: /[a-z]/i.test((opts.staticDefinitionSymbol || element)) ? new RegExp("[" + (opts.staticDefinitionSymbol || element) + "]", opts.casing ? "i" : "") : null, | ||
static: true, | ||
optionality: false, | ||
newBlockMarker: prevMatch === undefined ? "master" : (prevMatch.def !== element && prevMatch.static !== true), | ||
casing: null, | ||
def: opts.staticDefinitionSymbol || element, | ||
placeholder: opts.staticDefinitionSymbol !== undefined ? element : undefined, | ||
nativeDef: (escaped ? "'" : "") + element | ||
}); | ||
escaped = false; | ||
} | ||
} | ||
} | ||
// test definition => {fn: RegExp/function, static: true/false optionality: bool, newBlockMarker: bool, casing: null/upper/lower, def: definitionSymbol, placeholder: placeholder, mask: real maskDefinition} | ||
function insertTestDefinition(mtoken, element, position) { | ||
position = position !== undefined ? position : mtoken.matches.length; | ||
// console.log(element, position, currentToken.matches.length); | ||
// if (typeof opts.placeholder === "string") | ||
// console.log(opts.placeholder.charAt(currentToken.matches.length % opts.placeholder.length)); | ||
let prevMatch = mtoken.matches[position - 1]; | ||
if (regexMask) { | ||
if ( | ||
element.indexOf("[") === 0 || | ||
(escaped && /\\d|\\s|\\w|\\p/i.test(element)) || | ||
element === "." | ||
) { | ||
let flag = opts.casing ? "i" : ""; | ||
if (/\\p\{.*}/i.test(element)) flag += "u"; | ||
mtoken.matches.splice(position++, 0, { | ||
fn: new RegExp(element, flag), | ||
static: false, | ||
optionality: false, | ||
newBlockMarker: | ||
prevMatch === undefined ? "master" : prevMatch.def !== element, | ||
casing: null, | ||
def: element, | ||
placeholder: | ||
typeof opts.placeholder === "object" | ||
? opts.placeholder[currentToken.matches.length] | ||
: undefined, | ||
nativeDef: element | ||
}); | ||
} else { | ||
if (escaped) element = element[element.length - 1]; | ||
element.split("").forEach(function (lmnt, ndx) { | ||
prevMatch = mtoken.matches[position - 1]; | ||
mtoken.matches.splice(position++, 0, { | ||
fn: /[a-z]/i.test(opts.staticDefinitionSymbol || lmnt) | ||
? new RegExp( | ||
"[" + (opts.staticDefinitionSymbol || lmnt) + "]", | ||
opts.casing ? "i" : "" | ||
) | ||
: null, | ||
static: true, | ||
optionality: false, | ||
newBlockMarker: | ||
prevMatch === undefined | ||
? "master" | ||
: prevMatch.def !== lmnt && prevMatch.static !== true, | ||
casing: null, | ||
def: opts.staticDefinitionSymbol || lmnt, | ||
placeholder: | ||
opts.staticDefinitionSymbol !== undefined | ||
? lmnt | ||
: typeof opts.placeholder === "object" | ||
? opts.placeholder[currentToken.matches.length] | ||
: undefined, | ||
nativeDef: (escaped ? "'" : "") + lmnt | ||
}); | ||
}); | ||
} | ||
escaped = false; | ||
} else { | ||
const maskdef = | ||
(opts.definitions && opts.definitions[element]) || | ||
(opts.usePrototypeDefinitions && | ||
Inputmask.prototype.definitions[element]); | ||
if (maskdef && !escaped) { | ||
mtoken.matches.splice(position++, 0, { | ||
fn: maskdef.validator | ||
? typeof maskdef.validator === "string" | ||
? new RegExp(maskdef.validator, opts.casing ? "i" : "") | ||
: new (function () { | ||
this.test = maskdef.validator; | ||
})() | ||
: /./, | ||
static: maskdef.static || false, | ||
optionality: maskdef.optional || false, | ||
defOptionality: maskdef.optional || false, // indicator for an optional from the definition | ||
newBlockMarker: | ||
prevMatch === undefined || maskdef.optional | ||
? "master" | ||
: prevMatch.def !== (maskdef.definitionSymbol || element), | ||
casing: maskdef.casing, | ||
def: maskdef.definitionSymbol || element, | ||
placeholder: maskdef.placeholder, | ||
nativeDef: element, | ||
generated: maskdef.generated | ||
}); | ||
} else { | ||
mtoken.matches.splice(position++, 0, { | ||
fn: /[a-z]/i.test(opts.staticDefinitionSymbol || element) | ||
? new RegExp( | ||
"[" + (opts.staticDefinitionSymbol || element) + "]", | ||
opts.casing ? "i" : "" | ||
) | ||
: null, | ||
static: true, | ||
optionality: false, | ||
newBlockMarker: | ||
prevMatch === undefined | ||
? "master" | ||
: prevMatch.def !== element && prevMatch.static !== true, | ||
casing: null, | ||
def: opts.staticDefinitionSymbol || element, | ||
placeholder: | ||
opts.staticDefinitionSymbol !== undefined ? element : undefined, | ||
nativeDef: (escaped ? "'" : "") + element | ||
}); | ||
escaped = false; | ||
} | ||
} | ||
} | ||
function verifyGroupMarker(maskToken) { | ||
if (maskToken && maskToken.matches) { | ||
maskToken.matches.forEach(function (token, ndx) { | ||
var nextToken = maskToken.matches[ndx + 1]; | ||
if ((nextToken === undefined || (nextToken.matches === undefined || nextToken.isQuantifier === false)) && token && token.isGroup) { //this is not a group but a normal mask => convert | ||
token.isGroup = false; | ||
if (!regexMask) { | ||
insertTestDefinition(token, opts.groupmarker[0], 0); | ||
if (token.openGroup !== true) { | ||
insertTestDefinition(token, opts.groupmarker[1]); | ||
} | ||
} | ||
} | ||
verifyGroupMarker(token); | ||
}); | ||
} | ||
} | ||
function verifyGroupMarker(maskToken) { | ||
if (maskToken && maskToken.matches) { | ||
maskToken.matches.forEach(function (token, ndx) { | ||
const nextToken = maskToken.matches[ndx + 1]; | ||
if ( | ||
(nextToken === undefined || | ||
nextToken.matches === undefined || | ||
nextToken.isQuantifier === false) && | ||
token && | ||
token.isGroup | ||
) { | ||
// this is not a group but a normal mask => convert | ||
token.isGroup = false; | ||
if (!regexMask) { | ||
insertTestDefinition(token, opts.groupmarker[0], 0); | ||
if (token.openGroup !== true) { | ||
insertTestDefinition(token, opts.groupmarker[1]); | ||
} | ||
} | ||
} | ||
verifyGroupMarker(token); | ||
}); | ||
} | ||
} | ||
function defaultCase() { | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
insertTestDefinition(currentOpeningToken, m); | ||
if (currentOpeningToken.isAlternator) { //handle alternator a | b case | ||
alternator = openenings.pop(); | ||
for (var mndx = 0; mndx < alternator.matches.length; mndx++) { | ||
if (alternator.matches[mndx].isGroup) alternator.matches[mndx].isGroup = false; //don't mark alternate groups as group | ||
} | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
currentOpeningToken.matches.push(alternator); | ||
} else { | ||
currentToken.matches.push(alternator); | ||
} | ||
} | ||
} else { | ||
insertTestDefinition(currentToken, m); | ||
} | ||
} | ||
function defaultCase() { | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
insertTestDefinition(currentOpeningToken, m); | ||
if (currentOpeningToken.isAlternator) { | ||
// handle alternator a | b case | ||
alternator = openenings.pop(); | ||
for (let mndx = 0; mndx < alternator.matches.length; mndx++) { | ||
if (alternator.matches[mndx].isGroup) | ||
alternator.matches[mndx].isGroup = false; // don't mark alternate groups as group | ||
} | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
currentOpeningToken.matches.push(alternator); | ||
} else { | ||
currentToken.matches.push(alternator); | ||
} | ||
} | ||
} else { | ||
insertTestDefinition(currentToken, m); | ||
} | ||
} | ||
function reverseTokens(maskToken) { | ||
function reverseStatic(st) { | ||
if (st === opts.optionalmarker[0]) { | ||
st = opts.optionalmarker[1]; | ||
} else if (st === opts.optionalmarker[1]) { | ||
st = opts.optionalmarker[0]; | ||
} else if (st === opts.groupmarker[0]) { | ||
st = opts.groupmarker[1]; | ||
} else if (st === opts.groupmarker[1]) st = opts.groupmarker[0]; | ||
function reverseTokens(maskToken) { | ||
function reverseStatic(st) { | ||
if (st === opts.optionalmarker[0]) { | ||
st = opts.optionalmarker[1]; | ||
} else if (st === opts.optionalmarker[1]) { | ||
st = opts.optionalmarker[0]; | ||
} else if (st === opts.groupmarker[0]) { | ||
st = opts.groupmarker[1]; | ||
} else if (st === opts.groupmarker[1]) st = opts.groupmarker[0]; | ||
return st; | ||
} | ||
return st; | ||
} | ||
maskToken.matches = maskToken.matches.reverse(); | ||
for (var match in maskToken.matches) { | ||
if (Object.prototype.hasOwnProperty.call(maskToken.matches, match)) { | ||
var intMatch = parseInt(match); | ||
if (maskToken.matches[match].isQuantifier && maskToken.matches[intMatch + 1] && maskToken.matches[intMatch + 1].isGroup) { //reposition quantifier | ||
var qt = maskToken.matches[match]; | ||
maskToken.matches.splice(match, 1); | ||
maskToken.matches.splice(intMatch + 1, 0, qt); | ||
} | ||
if (maskToken.matches[match].matches !== undefined) { | ||
maskToken.matches[match] = reverseTokens(maskToken.matches[match]); | ||
} else { | ||
maskToken.matches[match] = reverseStatic(maskToken.matches[match]); | ||
} | ||
} | ||
} | ||
maskToken.matches = maskToken.matches.reverse(); | ||
for (const match in maskToken.matches) { | ||
if (Object.prototype.hasOwnProperty.call(maskToken.matches, match)) { | ||
const intMatch = parseInt(match); | ||
if ( | ||
maskToken.matches[match].isQuantifier && | ||
maskToken.matches[intMatch + 1] && | ||
maskToken.matches[intMatch + 1].isGroup | ||
) { | ||
// reposition quantifier | ||
const qt = maskToken.matches[match]; | ||
maskToken.matches.splice(match, 1); | ||
maskToken.matches.splice(intMatch + 1, 0, qt); | ||
} | ||
if (maskToken.matches[match].matches !== undefined) { | ||
maskToken.matches[match] = reverseTokens(maskToken.matches[match]); | ||
} else { | ||
maskToken.matches[match] = reverseStatic(maskToken.matches[match]); | ||
} | ||
} | ||
} | ||
return maskToken; | ||
} | ||
return maskToken; | ||
} | ||
function groupify(matches) { | ||
var groupToken = new MaskToken(true); | ||
groupToken.openGroup = false; | ||
groupToken.matches = matches; | ||
return groupToken; | ||
} | ||
function groupify(matches) { | ||
const groupToken = new MaskToken(true); | ||
groupToken.openGroup = false; | ||
groupToken.matches = matches; | ||
return groupToken; | ||
} | ||
function closeGroup() { | ||
// Group closing | ||
openingToken = openenings.pop(); | ||
openingToken.openGroup = false; //mark group as complete | ||
if (openingToken !== undefined) { | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
currentOpeningToken.matches.push(openingToken); | ||
if (currentOpeningToken.isAlternator) { //handle alternator (a) | (b) case | ||
alternator = openenings.pop(); | ||
for (var mndx = 0; mndx < alternator.matches.length; mndx++) { | ||
alternator.matches[mndx].isGroup = false; //don't mark alternate groups as group | ||
alternator.matches[mndx].alternatorGroup = false; | ||
} | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
currentOpeningToken.matches.push(alternator); | ||
} else { | ||
currentToken.matches.push(alternator); | ||
} | ||
} | ||
} else { | ||
currentToken.matches.push(openingToken); | ||
} | ||
} else { | ||
defaultCase(); | ||
} | ||
} | ||
function closeGroup() { | ||
// Group closing | ||
openingToken = openenings.pop(); | ||
openingToken.openGroup = false; // mark group as complete | ||
if (openingToken !== undefined) { | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
currentOpeningToken.matches.push(openingToken); | ||
if (currentOpeningToken.isAlternator) { | ||
// handle alternator (a) | (b) case | ||
alternator = openenings.pop(); | ||
for (let mndx = 0; mndx < alternator.matches.length; mndx++) { | ||
alternator.matches[mndx].isGroup = false; // don't mark alternate groups as group | ||
alternator.matches[mndx].alternatorGroup = false; | ||
} | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
currentOpeningToken.matches.push(alternator); | ||
} else { | ||
currentToken.matches.push(alternator); | ||
} | ||
} | ||
} else { | ||
currentToken.matches.push(openingToken); | ||
} | ||
} else { | ||
defaultCase(); | ||
} | ||
} | ||
function groupQuantifier(matches) { | ||
var lastMatch = matches.pop(); | ||
if (lastMatch.isQuantifier) { | ||
lastMatch = groupify([matches.pop(), lastMatch]); | ||
} | ||
return lastMatch; | ||
} | ||
function groupQuantifier(matches) { | ||
let lastMatch = matches.pop(); | ||
if (lastMatch.isQuantifier) { | ||
lastMatch = groupify([matches.pop(), lastMatch]); | ||
} | ||
return lastMatch; | ||
} | ||
if (regexMask) { | ||
opts.optionalmarker[0] = undefined; | ||
opts.optionalmarker[1] = undefined; | ||
} | ||
// console.log(mask); | ||
while ((match = regexMask ? regexTokenizer.exec(mask) : tokenizer.exec(mask))) { | ||
// console.log(match); | ||
m = match[0]; | ||
if (regexMask) { | ||
opts.optionalmarker[0] = undefined; | ||
opts.optionalmarker[1] = undefined; | ||
} | ||
// console.log(mask); | ||
while ( | ||
(match = regexMask ? regexTokenizer.exec(mask) : tokenizer.exec(mask)) | ||
) { | ||
// console.log(match); | ||
m = match[0]; | ||
if (regexMask) { | ||
switch (m.charAt(0)) { | ||
//Quantifier | ||
case "?": | ||
m = "{0,1}"; | ||
break; | ||
case "+": | ||
case "*": | ||
m = "{" + m + "}"; | ||
break; | ||
case "|": | ||
//regex mask alternator ex: [01][0-9]|2[0-3] => ([01][0-9]|2[0-3]) | ||
if (openenings.length === 0) { //wrap the mask in a group to form a regex alternator ([01][0-9]|2[0-3]) | ||
var altRegexGroup = groupify(currentToken.matches); | ||
altRegexGroup.openGroup = true; | ||
openenings.push(altRegexGroup); | ||
currentToken.matches = []; | ||
closeRegexGroup = true; | ||
} | ||
break; | ||
} | ||
switch (m) { | ||
case "\\d": | ||
m = "[0-9]"; | ||
break; | ||
case "\\p": //Unicode Categories | ||
m += regexTokenizer.exec(mask)[0]; // { | ||
m += regexTokenizer.exec(mask)[0]; // ?} | ||
break; | ||
case "(?:": //non capturing group | ||
case "(?=": //lookahead | ||
case "(?!": //negative lookahead | ||
case "(?<=": //lookbehind | ||
case "(?<!": //negative lookbehind | ||
// treat as group | ||
break; | ||
} | ||
} | ||
if (regexMask) { | ||
switch (m.charAt(0)) { | ||
// Quantifier | ||
case "?": | ||
m = "{0,1}"; | ||
break; | ||
case "+": | ||
case "*": | ||
m = "{" + m + "}"; | ||
break; | ||
case "|": | ||
// regex mask alternator ex: [01][0-9]|2[0-3] => ([01][0-9]|2[0-3]) | ||
if (openenings.length === 0) { | ||
// wrap the mask in a group to form a regex alternator ([01][0-9]|2[0-3]) | ||
const altRegexGroup = groupify(currentToken.matches); | ||
altRegexGroup.openGroup = true; | ||
openenings.push(altRegexGroup); | ||
currentToken.matches = []; | ||
closeRegexGroup = true; | ||
} | ||
break; | ||
} | ||
switch (m) { | ||
case "\\d": | ||
m = "[0-9]"; | ||
break; | ||
case "\\p": // Unicode Categories | ||
m += regexTokenizer.exec(mask)[0]; // { | ||
m += regexTokenizer.exec(mask)[0]; // ?} | ||
break; | ||
case "(?:": // non capturing group | ||
case "(?=": // lookahead | ||
case "(?!": // negative lookahead | ||
case "(?<=": // lookbehind | ||
case "(?<!": // negative lookbehind | ||
// treat as group | ||
break; | ||
} | ||
} | ||
if (escaped) { | ||
defaultCase(); | ||
continue; | ||
} | ||
switch (m.charAt(0)) { | ||
case "$": | ||
case "^": | ||
//ignore beginswith and endswith as in masking this makes no point | ||
if (!regexMask) { | ||
defaultCase(); | ||
} | ||
break; | ||
case opts.escapeChar: | ||
escaped = true; | ||
if (regexMask) defaultCase(); | ||
break; | ||
// optional closing | ||
case opts.optionalmarker[1]: | ||
case opts.groupmarker[1]: | ||
closeGroup(); | ||
break; | ||
case opts.optionalmarker[0]: | ||
// optional opening | ||
openenings.push(new MaskToken(false, true)); | ||
break; | ||
case opts.groupmarker[0]: | ||
// Group opening | ||
openenings.push(new MaskToken(true)); | ||
break; | ||
case opts.quantifiermarker[0]: | ||
//Quantifier | ||
var quantifier = new MaskToken(false, false, true); | ||
if (escaped) { | ||
defaultCase(); | ||
continue; | ||
} | ||
switch (m.charAt(0)) { | ||
case "$": | ||
case "^": | ||
// ignore beginswith and endswith as in masking this makes no point | ||
if (!regexMask) { | ||
defaultCase(); | ||
} | ||
break; | ||
case opts.escapeChar: | ||
escaped = true; | ||
if (regexMask) defaultCase(); | ||
break; | ||
// optional closing | ||
case opts.optionalmarker[1]: | ||
case opts.groupmarker[1]: | ||
closeGroup(); | ||
break; | ||
case opts.optionalmarker[0]: | ||
// optional opening | ||
openenings.push(new MaskToken(false, true)); | ||
break; | ||
case opts.groupmarker[0]: | ||
// Group opening | ||
openenings.push(new MaskToken(true)); | ||
break; | ||
case opts.quantifiermarker[0]: | ||
// Quantifier | ||
var quantifier = new MaskToken(false, false, true); | ||
m = m.replace(/[{}?]/g, ""); //? matches lazy quantifiers | ||
var mqj = m.split("|"), | ||
mq = mqj[0].split(","), | ||
mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), | ||
mq1 = mq.length === 1 ? mq0 : (isNaN(mq[1]) ? mq[1] : parseInt(mq[1])), | ||
mqJit = isNaN(mqj[1]) ? mqj[1] : parseInt(mqj[1]); | ||
if (mq0 === "*" || mq0 === "+") { | ||
mq0 = mq1 === "*" ? 0 : 1; | ||
} | ||
quantifier.quantifier = { | ||
min: mq0, | ||
max: mq1, | ||
jit: mqJit | ||
}; | ||
var matches = openenings.length > 0 ? openenings[openenings.length - 1].matches : currentToken.matches; | ||
match = matches.pop(); | ||
// if (match.isAlternator) { //handle quantifier in an alternation [0-9]{2}|[0-9]{3} | ||
// matches.push(match); //push back alternator | ||
// matches = match.matches; //remap target matches | ||
// var groupToken = new MaskToken(true); | ||
// var tmpMatch = matches.pop(); | ||
// matches.push(groupToken); //push the group | ||
// matches = groupToken.matches; | ||
// match = tmpMatch; | ||
// } | ||
if (!match.isGroup) { | ||
match = groupify([match]); | ||
} | ||
matches.push(match); | ||
matches.push(quantifier); | ||
m = m.replace(/[{}?]/g, ""); // ? matches lazy quantifiers | ||
var mqj = m.split("|"), | ||
mq = mqj[0].split(","), | ||
mq0 = isNaN(mq[0]) ? mq[0] : parseInt(mq[0]), | ||
mq1 = mq.length === 1 ? mq0 : isNaN(mq[1]) ? mq[1] : parseInt(mq[1]), | ||
mqJit = isNaN(mqj[1]) ? mqj[1] : parseInt(mqj[1]); | ||
if (mq0 === "*" || mq0 === "+") { | ||
mq0 = mq1 === "*" ? 0 : 1; | ||
} | ||
quantifier.quantifier = { | ||
min: mq0, | ||
max: mq1, | ||
jit: mqJit | ||
}; | ||
var matches = | ||
openenings.length > 0 | ||
? openenings[openenings.length - 1].matches | ||
: currentToken.matches; | ||
match = matches.pop(); | ||
// if (match.isAlternator) { //handle quantifier in an alternation [0-9]{2}|[0-9]{3} | ||
// matches.push(match); //push back alternator | ||
// matches = match.matches; //remap target matches | ||
// var groupToken = new MaskToken(true); | ||
// var tmpMatch = matches.pop(); | ||
// matches.push(groupToken); //push the group | ||
// matches = groupToken.matches; | ||
// match = tmpMatch; | ||
// } | ||
if (!match.isGroup) { | ||
match = groupify([match]); | ||
} | ||
matches.push(match); | ||
matches.push(quantifier); | ||
break; | ||
case opts.alternatormarker: | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
var subToken = currentOpeningToken.matches[currentOpeningToken.matches.length - 1]; | ||
if (currentOpeningToken.openGroup && //regexp alt syntax | ||
(subToken.matches === undefined || (subToken.isGroup === false && subToken.isAlternator === false))) { //alternations within group | ||
lastMatch = openenings.pop(); | ||
} else { | ||
lastMatch = groupQuantifier(currentOpeningToken.matches); | ||
} | ||
} else { | ||
lastMatch = groupQuantifier(currentToken.matches); | ||
} | ||
if (lastMatch.isAlternator) { | ||
openenings.push(lastMatch); | ||
} else { | ||
if (lastMatch.alternatorGroup) { | ||
alternator = openenings.pop(); | ||
lastMatch.alternatorGroup = false; | ||
} else { | ||
alternator = new MaskToken(false, false, false, true); | ||
} | ||
alternator.matches.push(lastMatch); | ||
openenings.push(alternator); | ||
if (lastMatch.openGroup) { //regexp alt syntax | ||
lastMatch.openGroup = false; | ||
var alternatorGroup = new MaskToken(true); | ||
alternatorGroup.alternatorGroup = true; | ||
openenings.push(alternatorGroup); | ||
} | ||
} | ||
break; | ||
default: | ||
defaultCase(); | ||
} | ||
} | ||
break; | ||
case opts.alternatormarker: | ||
if (openenings.length > 0) { | ||
currentOpeningToken = openenings[openenings.length - 1]; | ||
const subToken = | ||
currentOpeningToken.matches[currentOpeningToken.matches.length - 1]; | ||
if ( | ||
currentOpeningToken.openGroup && // regexp alt syntax | ||
(subToken.matches === undefined || | ||
(subToken.isGroup === false && subToken.isAlternator === false)) | ||
) { | ||
// alternations within group | ||
lastMatch = openenings.pop(); | ||
} else { | ||
lastMatch = groupQuantifier(currentOpeningToken.matches); | ||
} | ||
} else { | ||
lastMatch = groupQuantifier(currentToken.matches); | ||
} | ||
if (lastMatch.isAlternator) { | ||
openenings.push(lastMatch); | ||
} else { | ||
if (lastMatch.alternatorGroup) { | ||
alternator = openenings.pop(); | ||
lastMatch.alternatorGroup = false; | ||
} else { | ||
alternator = new MaskToken(false, false, false, true); | ||
} | ||
alternator.matches.push(lastMatch); | ||
openenings.push(alternator); | ||
if (lastMatch.openGroup) { | ||
// regexp alt syntax | ||
lastMatch.openGroup = false; | ||
const alternatorGroup = new MaskToken(true); | ||
alternatorGroup.alternatorGroup = true; | ||
openenings.push(alternatorGroup); | ||
} | ||
} | ||
break; | ||
default: | ||
defaultCase(); | ||
} | ||
} | ||
if (closeRegexGroup) closeGroup(); | ||
if (closeRegexGroup) closeGroup(); | ||
while (openenings.length > 0) { | ||
openingToken = openenings.pop(); | ||
currentToken.matches.push(openingToken); | ||
} | ||
if (currentToken.matches.length > 0) { | ||
verifyGroupMarker(currentToken); | ||
maskTokens.push(currentToken); | ||
} | ||
while (openenings.length > 0) { | ||
openingToken = openenings.pop(); | ||
currentToken.matches.push(openingToken); | ||
} | ||
if (currentToken.matches.length > 0) { | ||
verifyGroupMarker(currentToken); | ||
maskTokens.push(currentToken); | ||
} | ||
if (opts.numericInput || opts.isRTL) { | ||
reverseTokens(maskTokens[0]); | ||
} | ||
// console.log(JSON.stringify(maskTokens)); | ||
return maskTokens; | ||
if (opts.numericInput || opts.isRTL) { | ||
reverseTokens(maskTokens[0]); | ||
} | ||
// console.log(JSON.stringify(maskTokens)); | ||
return maskTokens; | ||
} |
516
lib/mask.js
@@ -1,247 +0,325 @@ | ||
import {keys} from "./keycode.js"; | ||
import {caret, getBuffer, getBufferTemplate, getLastValidPosition, resetMaskSet, seekNext} from "./positioning"; | ||
import {applyInputValue, clearOptionalTail, writeBuffer} from "./inputHandling"; | ||
import {EventRuler} from "./eventruler"; | ||
import {iphone, mobile} from "./environment"; | ||
import {isComplete} from "./validation"; | ||
import {EventHandlers} from "./eventhandlers"; | ||
import { iphone, mobile } from "./environment"; | ||
import { EventHandlers } from "./eventhandlers"; | ||
import { EventRuler } from "./eventruler"; | ||
import { | ||
applyInputValue, | ||
clearOptionalTail, | ||
writeBuffer | ||
} from "./inputHandling"; | ||
import { | ||
caret, | ||
getBuffer, | ||
getBufferTemplate, | ||
getLastValidPosition, | ||
resetMaskSet, | ||
seekNext | ||
} from "./positioning"; | ||
import { isComplete } from "./validation"; | ||
export {mask}; | ||
export { mask }; | ||
//todo put on the prototype? | ||
// todo put on the prototype? | ||
function mask() { | ||
const inputmask = this, | ||
opts = this.opts, | ||
el = this.el, $ = this.dependencyLib; | ||
const inputmask = this, | ||
opts = this.opts, | ||
el = this.el, | ||
$ = this.dependencyLib; | ||
function isElementTypeSupported(input, opts) { | ||
function patchValueProperty(npt) { | ||
let valueGet, valueSet; | ||
function isElementTypeSupported(input, opts) { | ||
function patchValueProperty(npt) { | ||
var valueGet; | ||
var valueSet; | ||
function patchValhook(type) { | ||
if ( | ||
$.valHooks && | ||
($.valHooks[type] === undefined || | ||
$.valHooks[type].inputmaskpatch !== true) | ||
) { | ||
const valhookGet = | ||
$.valHooks[type] && $.valHooks[type].get | ||
? $.valHooks[type].get | ||
: function (elem) { | ||
return elem.value; | ||
}, | ||
valhookSet = | ||
$.valHooks[type] && $.valHooks[type].set | ||
? $.valHooks[type].set | ||
: function (elem, value) { | ||
elem.value = value; | ||
return elem; | ||
}; | ||
function patchValhook(type) { | ||
if ($.valHooks && ($.valHooks[type] === undefined || $.valHooks[type].inputmaskpatch !== true)) { | ||
var valhookGet = $.valHooks[type] && $.valHooks[type].get ? $.valHooks[type].get : function (elem) { | ||
return elem.value; | ||
}; | ||
var valhookSet = $.valHooks[type] && $.valHooks[type].set ? $.valHooks[type].set : function (elem, value) { | ||
elem.value = value; | ||
return elem; | ||
}; | ||
$.valHooks[type] = { | ||
get: function (elem) { | ||
if (elem.inputmask) { | ||
if (elem.inputmask.opts.autoUnmask) { | ||
return elem.inputmask.unmaskedvalue(); | ||
} else { | ||
var result = valhookGet(elem); | ||
return getLastValidPosition.call(inputmask, undefined, undefined, elem.inputmask.maskset.validPositions) !== -1 || opts.nullable !== true ? result : ""; | ||
} | ||
} else { | ||
return valhookGet(elem); | ||
} | ||
}, | ||
set: function (elem, value) { | ||
var result = valhookSet(elem, value); | ||
if (elem.inputmask) { | ||
applyInputValue(elem, value); | ||
} | ||
return result; | ||
}, | ||
inputmaskpatch: true | ||
}; | ||
} | ||
} | ||
function getter() { | ||
if (this.inputmask) { | ||
return this.inputmask.opts.autoUnmask ? | ||
this.inputmask.unmaskedvalue() : | ||
(getLastValidPosition.call(inputmask) !== -1 || opts.nullable !== true ? | ||
(((this.inputmask.shadowRoot || this.ownerDocument).activeElement) === this && opts.clearMaskOnLostFocus ? | ||
(inputmask.isRTL ? clearOptionalTail.call(inputmask, getBuffer.call(inputmask).slice()).reverse() : clearOptionalTail.call(inputmask, getBuffer.call(inputmask).slice())).join("") : | ||
valueGet.call(this)) : | ||
""); | ||
$.valHooks[type] = { | ||
get: function (elem) { | ||
if (elem.inputmask) { | ||
if (elem.inputmask.opts.autoUnmask) { | ||
return elem.inputmask.unmaskedvalue(); | ||
} else { | ||
return valueGet.call(this); | ||
const result = valhookGet(elem); | ||
return getLastValidPosition.call( | ||
inputmask, | ||
undefined, | ||
undefined, | ||
elem.inputmask.maskset.validPositions | ||
) !== -1 || opts.nullable !== true | ||
? result | ||
: ""; | ||
} | ||
} | ||
} else { | ||
return valhookGet(elem); | ||
} | ||
}, | ||
set: function (elem, value) { | ||
const result = valhookSet(elem, value); | ||
if (elem.inputmask) { | ||
applyInputValue(elem, value); | ||
} | ||
return result; | ||
}, | ||
inputmaskpatch: true | ||
}; | ||
} | ||
} | ||
function setter(value) { | ||
valueSet.call(this, value); | ||
if (this.inputmask) { | ||
applyInputValue(this, value); | ||
} | ||
} | ||
function getter() { | ||
if (this.inputmask) { | ||
return this.inputmask.opts.autoUnmask | ||
? this.inputmask.unmaskedvalue() | ||
: getLastValidPosition.call(inputmask) !== -1 || | ||
opts.nullable !== true | ||
? (this.inputmask.shadowRoot || this.ownerDocument) | ||
.activeElement === this && opts.clearMaskOnLostFocus | ||
? (inputmask.isRTL | ||
? clearOptionalTail | ||
.call(inputmask, getBuffer.call(inputmask).slice()) | ||
.reverse() | ||
: clearOptionalTail.call( | ||
inputmask, | ||
getBuffer.call(inputmask).slice() | ||
) | ||
).join("") | ||
: valueGet.call(this) | ||
: ""; | ||
} else { | ||
return valueGet.call(this); | ||
} | ||
} | ||
function installNativeValueSetFallback(npt) { | ||
EventRuler.on(npt, "mouseenter", function () { | ||
let input = this, | ||
value = input.inputmask._valueGet(true), | ||
bufferValue = (input.inputmask.isRTL ? getBuffer.call(input.inputmask).slice().reverse() : getBuffer.call(input.inputmask)).join(""); | ||
if (value != bufferValue) { | ||
applyInputValue(input, value); | ||
} | ||
}); | ||
} | ||
function setter(value) { | ||
valueSet.call(this, value); | ||
if (this.inputmask) { | ||
applyInputValue(this, value); | ||
} | ||
} | ||
if (!npt.inputmask.__valueGet) { | ||
if (opts.noValuePatching !== true) { | ||
if (Object.getOwnPropertyDescriptor) { | ||
var valueProperty = Object.getPrototypeOf ? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(npt), "value") : undefined; | ||
if (valueProperty && valueProperty.get && valueProperty.set) { | ||
valueGet = valueProperty.get; | ||
valueSet = valueProperty.set; | ||
Object.defineProperty(npt, "value", { | ||
get: getter, | ||
set: setter, | ||
configurable: true | ||
}); | ||
} else if (npt.tagName.toLowerCase() !== "input") { | ||
valueGet = function () { | ||
return this.textContent; | ||
}; | ||
valueSet = function (value) { | ||
this.textContent = value; | ||
}; | ||
Object.defineProperty(npt, "value", { | ||
get: getter, | ||
set: setter, | ||
configurable: true | ||
}); | ||
} | ||
} else if (document.__lookupGetter__ && npt.__lookupGetter__("value")) { | ||
valueGet = npt.__lookupGetter__("value"); | ||
valueSet = npt.__lookupSetter__("value"); | ||
function installNativeValueSetFallback(npt) { | ||
EventRuler.on(npt, "mouseenter", function () { | ||
const input = this, | ||
value = input.inputmask._valueGet(true), | ||
bufferValue = ( | ||
input.inputmask.isRTL | ||
? getBuffer.call(input.inputmask).slice().reverse() | ||
: getBuffer.call(input.inputmask) | ||
).join(""); | ||
if (value != bufferValue) { | ||
applyInputValue(input, value); | ||
} | ||
}); | ||
} | ||
npt.__defineGetter__("value", getter); | ||
npt.__defineSetter__("value", setter); | ||
} | ||
npt.inputmask.__valueGet = valueGet; //store native property getter | ||
npt.inputmask.__valueSet = valueSet; //store native property setter | ||
} | ||
npt.inputmask._valueGet = function (overruleRTL) { | ||
return inputmask.isRTL && overruleRTL !== true ? valueGet.call(this.el).split("").reverse().join("") : valueGet.call(this.el); | ||
}; | ||
npt.inputmask._valueSet = function (value, overruleRTL) { //null check is needed for IE8 => otherwise converts to "null" | ||
valueSet.call(this.el, (value === null || value === undefined) ? "" : ((overruleRTL !== true && inputmask.isRTL) ? value.split("").reverse().join("") : value)); | ||
}; | ||
if (!npt.inputmask.__valueGet) { | ||
if (opts.noValuePatching !== true) { | ||
if (Object.getOwnPropertyDescriptor) { | ||
const valueProperty = Object.getPrototypeOf | ||
? Object.getOwnPropertyDescriptor( | ||
Object.getPrototypeOf(npt), | ||
"value" | ||
) | ||
: undefined; | ||
if (valueProperty && valueProperty.get && valueProperty.set) { | ||
valueGet = valueProperty.get; | ||
valueSet = valueProperty.set; | ||
Object.defineProperty(npt, "value", { | ||
get: getter, | ||
set: setter, | ||
configurable: true | ||
}); | ||
} else if (npt.tagName.toLowerCase() !== "input") { | ||
valueGet = function () { | ||
return this.textContent; | ||
}; | ||
valueSet = function (value) { | ||
this.textContent = value; | ||
}; | ||
Object.defineProperty(npt, "value", { | ||
get: getter, | ||
set: setter, | ||
configurable: true | ||
}); | ||
} | ||
} else if ( | ||
document.__lookupGetter__ && | ||
npt.__lookupGetter__("value") | ||
) { | ||
valueGet = npt.__lookupGetter__("value"); | ||
valueSet = npt.__lookupSetter__("value"); | ||
if (valueGet === undefined) { //jquery.val fallback | ||
valueGet = function () { | ||
return this.value; | ||
}; | ||
valueSet = function (value) { | ||
this.value = value; | ||
}; | ||
patchValhook(npt.type); | ||
installNativeValueSetFallback(npt); | ||
} | ||
} | ||
npt.__defineGetter__("value", getter); | ||
npt.__defineSetter__("value", setter); | ||
} | ||
npt.inputmask.__valueGet = valueGet; // store native property getter | ||
npt.inputmask.__valueSet = valueSet; // store native property setter | ||
} | ||
npt.inputmask._valueGet = function (overruleRTL) { | ||
return inputmask.isRTL && overruleRTL !== true | ||
? valueGet.call(this.el).split("").reverse().join("") | ||
: valueGet.call(this.el); | ||
}; | ||
npt.inputmask._valueSet = function (value, overruleRTL) { | ||
// null check is needed for IE8 => otherwise converts to "null" | ||
valueSet.call( | ||
this.el, | ||
value === null || value === undefined | ||
? "" | ||
: overruleRTL !== true && inputmask.isRTL | ||
? value.split("").reverse().join("") | ||
: value | ||
); | ||
}; | ||
// if (input.tagName.toLowerCase() !== "textarea") { | ||
// opts.ignorables.push(keys.Enter); | ||
// } | ||
var elementType = input.getAttribute("type"); | ||
var isSupported = (input.tagName.toLowerCase() === "input" && opts.supportsInputType.includes(elementType)) || input.isContentEditable || input.tagName.toLowerCase() === "textarea"; | ||
if (!isSupported) { | ||
if (input.tagName.toLowerCase() === "input") { | ||
var el = document.createElement("input"); | ||
el.setAttribute("type", elementType); | ||
isSupported = el.type === "text"; //apply mask only if the type is not natively supported | ||
el = null; | ||
} else { | ||
isSupported = "partial"; | ||
} | ||
if (valueGet === undefined) { | ||
// jquery.val fallback | ||
valueGet = function () { | ||
return this.value; | ||
}; | ||
valueSet = function (value) { | ||
this.value = value; | ||
}; | ||
patchValhook(npt.type); | ||
installNativeValueSetFallback(npt); | ||
} | ||
if (isSupported !== false) { | ||
patchValueProperty(input); | ||
} else { | ||
input.inputmask = undefined; | ||
} | ||
return isSupported; | ||
} | ||
} | ||
//unbind all events - to make sure that no other mask will interfere when re-masking | ||
EventRuler.off(el); | ||
var isSupported = isElementTypeSupported(el, opts); | ||
// if (input.tagName.toLowerCase() !== "textarea") { | ||
// opts.ignorables.push(keys.Enter); | ||
// } | ||
let elementType = input.getAttribute("type"), | ||
isSupported = | ||
(input.tagName.toLowerCase() === "input" && | ||
opts.supportsInputType.includes(elementType)) || | ||
input.isContentEditable || | ||
input.tagName.toLowerCase() === "textarea"; | ||
if (!isSupported) { | ||
if (input.tagName.toLowerCase() === "input") { | ||
let el = document.createElement("input"); | ||
el.setAttribute("type", elementType); | ||
isSupported = el.type === "text"; // apply mask only if the type is not natively supported | ||
el = null; | ||
} else { | ||
isSupported = "partial"; | ||
} | ||
} | ||
if (isSupported !== false) { | ||
inputmask.originalPlaceholder = el.placeholder; | ||
patchValueProperty(input); | ||
} else { | ||
input.inputmask = undefined; | ||
} | ||
return isSupported; | ||
} | ||
//read maxlength prop from el | ||
inputmask.maxLength = el !== undefined ? el.maxLength : undefined; | ||
if (inputmask.maxLength === -1) inputmask.maxLength = undefined; | ||
if ("inputMode" in el && el.getAttribute("inputmode") === null) { | ||
el.inputMode = opts.inputmode; | ||
el.setAttribute("inputmode", opts.inputmode); | ||
} | ||
// unbind all events - to make sure that no other mask will interfere when re-masking | ||
EventRuler.off(el); | ||
const isSupported = isElementTypeSupported(el, opts); | ||
if (isSupported !== false) { | ||
inputmask.originalPlaceholder = el.placeholder; | ||
// read maxlength prop from el | ||
inputmask.maxLength = el !== undefined ? el.maxLength : undefined; | ||
if (inputmask.maxLength === -1) inputmask.maxLength = undefined; | ||
if ("inputMode" in el && el.getAttribute("inputmode") === null) { | ||
el.inputMode = opts.inputmode; | ||
el.setAttribute("inputmode", opts.inputmode); | ||
} | ||
if (isSupported === true) { | ||
opts.showMaskOnFocus = opts.showMaskOnFocus && ["cc-number", "cc-exp"].indexOf(el.autocomplete) === -1; | ||
if (iphone) { | ||
//selecting the caret shows as a selection on iphone | ||
opts.insertModeVisual = false; | ||
//disable autocorrect | ||
el.setAttribute("autocorrect", "off"); | ||
} | ||
if (isSupported === true) { | ||
opts.showMaskOnFocus = | ||
opts.showMaskOnFocus && | ||
["cc-number", "cc-exp"].indexOf(el.autocomplete) === -1; | ||
if (iphone) { | ||
// selecting the caret shows as a selection on iphone | ||
opts.insertModeVisual = false; | ||
// disable autocorrect | ||
el.setAttribute("autocorrect", "off"); | ||
} | ||
//bind events | ||
EventRuler.on(el, "submit", EventHandlers.submitEvent); | ||
EventRuler.on(el, "reset", EventHandlers.resetEvent); | ||
EventRuler.on(el, "blur", EventHandlers.blurEvent); | ||
EventRuler.on(el, "focus", EventHandlers.focusEvent); | ||
EventRuler.on(el, "invalid", EventHandlers.invalidEvent); | ||
EventRuler.on(el, "click", EventHandlers.clickEvent); | ||
EventRuler.on(el, "mouseleave", EventHandlers.mouseleaveEvent); | ||
EventRuler.on(el, "mouseenter", EventHandlers.mouseenterEvent); | ||
EventRuler.on(el, "paste", EventHandlers.pasteEvent); | ||
EventRuler.on(el, "cut", EventHandlers.cutEvent); | ||
EventRuler.on(el, "complete", opts.oncomplete); | ||
EventRuler.on(el, "incomplete", opts.onincomplete); | ||
EventRuler.on(el, "cleared", opts.oncleared); | ||
if (opts.inputEventOnly !== true) { | ||
EventRuler.on(el, "keydown", EventHandlers.keyEvent); | ||
} | ||
if (mobile || opts.inputEventOnly) { | ||
el.removeAttribute("maxLength"); | ||
} | ||
EventRuler.on(el, "input", EventHandlers.inputFallBackEvent); | ||
// EventRuler.on(el, "beforeinput", EventHandlers.beforeInputEvent); //https://github.com/w3c/input-events - to implement | ||
} | ||
EventRuler.on(el, "setvalue", EventHandlers.setValueEvent); | ||
// bind events | ||
EventRuler.on(el, "submit", EventHandlers.submitEvent); | ||
EventRuler.on(el, "reset", EventHandlers.resetEvent); | ||
EventRuler.on(el, "blur", EventHandlers.blurEvent); | ||
EventRuler.on(el, "focus", EventHandlers.focusEvent); | ||
EventRuler.on(el, "invalid", EventHandlers.invalidEvent); | ||
EventRuler.on(el, "click", EventHandlers.clickEvent); | ||
EventRuler.on(el, "mouseleave", EventHandlers.mouseleaveEvent); | ||
EventRuler.on(el, "mouseenter", EventHandlers.mouseenterEvent); | ||
EventRuler.on(el, "paste", EventHandlers.pasteEvent); | ||
EventRuler.on(el, "cut", EventHandlers.cutEvent); | ||
EventRuler.on(el, "complete", opts.oncomplete); | ||
EventRuler.on(el, "incomplete", opts.onincomplete); | ||
EventRuler.on(el, "cleared", opts.oncleared); | ||
if (opts.inputEventOnly !== true) { | ||
EventRuler.on(el, "keydown", EventHandlers.keyEvent); | ||
} | ||
if (mobile || opts.inputEventOnly) { | ||
el.removeAttribute("maxLength"); | ||
} | ||
EventRuler.on(el, "input", EventHandlers.inputFallBackEvent); | ||
// EventRuler.on(el, "beforeinput", EventHandlers.beforeInputEvent); //https://github.com/w3c/input-events - to implement | ||
} | ||
EventRuler.on(el, "setvalue", EventHandlers.setValueEvent); | ||
//apply mask | ||
inputmask.applyMaskHook === undefined || inputmask.applyMaskHook.call(inputmask); | ||
// apply mask | ||
inputmask.applyMaskHook === undefined || inputmask.applyMaskHook(); | ||
getBufferTemplate.call(inputmask).join(""); //initialize the buffer and getmasklength | ||
inputmask.undoValue = inputmask._valueGet(true); | ||
var activeElement = (el.inputmask.shadowRoot || el.ownerDocument).activeElement; | ||
if (el.inputmask._valueGet(true) !== "" || opts.clearMaskOnLostFocus === false || activeElement === el) { | ||
applyInputValue(el, el.inputmask._valueGet(true), opts); | ||
var buffer = getBuffer.call(inputmask).slice(); | ||
if (isComplete.call(inputmask, buffer) === false) { | ||
if (opts.clearIncomplete) { | ||
resetMaskSet.call(inputmask, false); | ||
} | ||
} | ||
if (opts.clearMaskOnLostFocus && activeElement !== el) { | ||
if (getLastValidPosition.call(inputmask) === -1) { | ||
buffer = []; | ||
} else { | ||
clearOptionalTail.call(inputmask, buffer); | ||
} | ||
} | ||
if (opts.clearMaskOnLostFocus === false || (opts.showMaskOnFocus && activeElement === el) || el.inputmask._valueGet(true) !== "") { | ||
writeBuffer(el, buffer); | ||
} | ||
if (activeElement === el) { //position the caret when in focus | ||
caret.call(inputmask, el, seekNext.call(inputmask, getLastValidPosition.call(inputmask))); | ||
} | ||
getBufferTemplate.call(inputmask).join(""); // initialize the buffer and getmasklength | ||
inputmask.undoValue = inputmask._valueGet(true); | ||
const activeElement = (el.inputmask.shadowRoot || el.ownerDocument) | ||
.activeElement; | ||
if ( | ||
el.inputmask._valueGet(true) !== "" || | ||
opts.clearMaskOnLostFocus === false || | ||
activeElement === el | ||
) { | ||
applyInputValue(el, el.inputmask._valueGet(true), opts); | ||
let buffer = getBuffer.call(inputmask).slice(); | ||
if (isComplete.call(inputmask, buffer) === false) { | ||
if (opts.clearIncomplete) { | ||
resetMaskSet.call(inputmask, false); | ||
} | ||
} | ||
if (opts.clearMaskOnLostFocus && activeElement !== el) { | ||
if (getLastValidPosition.call(inputmask) === -1) { | ||
buffer = []; | ||
} else { | ||
clearOptionalTail.call(inputmask, buffer); | ||
} | ||
} | ||
if ( | ||
opts.clearMaskOnLostFocus === false || | ||
(opts.showMaskOnFocus && activeElement === el) || | ||
el.inputmask._valueGet(true) !== "" | ||
) { | ||
writeBuffer(el, buffer); | ||
} | ||
if (activeElement === el) { | ||
// position the caret when in focus | ||
caret.call( | ||
inputmask, | ||
el, | ||
seekNext.call(inputmask, getLastValidPosition.call(inputmask)) | ||
); | ||
} | ||
} | ||
} | ||
} |
export default function (isGroup, isOptional, isQuantifier, isAlternator) { | ||
this.matches = []; | ||
this.openGroup = isGroup || false; | ||
this.alternatorGroup = false; | ||
this.isGroup = isGroup || false; | ||
this.isOptional = isOptional || false; | ||
this.isQuantifier = isQuantifier || false; | ||
this.isAlternator = isAlternator || false; | ||
this.quantifier = { | ||
min: 1, | ||
max: 1 | ||
}; | ||
} | ||
this.matches = []; | ||
this.openGroup = isGroup || false; | ||
this.alternatorGroup = false; | ||
this.isGroup = isGroup || false; | ||
this.isOptional = isOptional || false; | ||
this.isQuantifier = isQuantifier || false; | ||
this.isAlternator = isAlternator || false; | ||
this.quantifier = { | ||
min: 1, | ||
max: 1 | ||
}; | ||
} |
// https://tc39.github.io/ecma262/#sec-array.prototype.includes | ||
if (!Array.prototype.includes) { | ||
Object.defineProperty(Array.prototype, "includes", { | ||
value: function(searchElement, fromIndex) { | ||
// eslint-disable-next-line no-extend-native | ||
Object.defineProperty(Array.prototype, "includes", { | ||
value: function (searchElement, fromIndex) { | ||
// 1. Let O be ? ToObject(this value). | ||
if (this == null) { | ||
throw new TypeError('"this" is null or not defined'); | ||
} | ||
// 1. Let O be ? ToObject(this value). | ||
if (this == null) { | ||
throw new TypeError("\"this\" is null or not defined"); | ||
} | ||
const o = Object(this), | ||
// 2. Let len be ? ToLength(? Get(O, "length")). | ||
len = o.length >>> 0; | ||
var o = Object(this); | ||
// 3. If len is 0, return false. | ||
if (len === 0) { | ||
return false; | ||
} | ||
// 2. Let len be ? ToLength(? Get(O, "length")). | ||
var len = o.length >>> 0; | ||
// 4. Let n be ? ToInteger(fromIndex). | ||
// (If fromIndex is undefined, this step produces the value 0.) | ||
let n = fromIndex | 0, | ||
// 5. If n ≥ 0, then | ||
// a. Let k be n. | ||
// 6. Else n < 0, | ||
// a. Let k be len + n. | ||
// b. If k < 0, let k be 0. | ||
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); | ||
// 3. If len is 0, return false. | ||
if (len === 0) { | ||
return false; | ||
} | ||
// 7. Repeat, while k < len | ||
while (k < len) { | ||
// a. Let elementK be the result of ? Get(O, ! ToString(k)). | ||
// b. If SameValueZero(searchElement, elementK) is true, return true. | ||
// c. Increase k by 1. | ||
// NOTE: === provides the correct "SameValueZero" comparison needed here. | ||
if (o[k] === searchElement) { | ||
return true; | ||
} | ||
k++; | ||
} | ||
// 4. Let n be ? ToInteger(fromIndex). | ||
// (If fromIndex is undefined, this step produces the value 0.) | ||
var n = fromIndex | 0; | ||
// 5. If n ≥ 0, then | ||
// a. Let k be n. | ||
// 6. Else n < 0, | ||
// a. Let k be len + n. | ||
// b. If k < 0, let k be 0. | ||
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); | ||
// 7. Repeat, while k < len | ||
while (k < len) { | ||
// a. Let elementK be the result of ? Get(O, ! ToString(k)). | ||
// b. If SameValueZero(searchElement, elementK) is true, return true. | ||
// c. Increase k by 1. | ||
// NOTE: === provides the correct "SameValueZero" comparison needed here. | ||
if (o[k] === searchElement) { | ||
return true; | ||
} | ||
k++; | ||
} | ||
// 8. Return false | ||
return false; | ||
} | ||
}); | ||
} | ||
// 8. Return false | ||
return false; | ||
} | ||
}); | ||
} |
@@ -1,10 +0,21 @@ | ||
const reduce = Function.bind.call(Function.call, Array.prototype.reduce); | ||
const isEnumerable = Function.bind.call(Function.call, Object.prototype.propertyIsEnumerable); | ||
const concat = Function.bind.call(Function.call, Array.prototype.concat); | ||
const keys = Object.keys; | ||
const reduce = Function.bind.call(Function.call, Array.prototype.reduce), | ||
isEnumerable = Function.bind.call( | ||
Function.call, | ||
Object.prototype.propertyIsEnumerable | ||
), | ||
concat = Function.bind.call(Function.call, Array.prototype.concat), | ||
keys = Object.keys; | ||
if (!Object.entries) { | ||
Object.entries = function entries(O) { | ||
return reduce(keys(O), (e, k) => concat(e, typeof k === 'string' && isEnumerable(O, k) ? [[k, O[k]]] : []), []); | ||
}; | ||
} | ||
Object.entries = function entries(O) { | ||
return reduce( | ||
keys(O), | ||
(e, k) => | ||
concat( | ||
e, | ||
typeof k === "string" && isEnumerable(O, k) ? [[k, O[k]]] : [] | ||
), | ||
[] | ||
); | ||
}; | ||
} |
if (typeof Object.getPrototypeOf !== "function") { | ||
Object.getPrototypeOf = typeof "test".__proto__ === "object" ? function (object) { | ||
return object.__proto__; | ||
} : function (object) { | ||
return object.constructor.prototype; | ||
}; | ||
} | ||
Object.getPrototypeOf = | ||
typeof "test".__proto__ === "object" | ||
? function (object) { | ||
return object.__proto__; | ||
} | ||
: function (object) { | ||
return object.constructor.prototype; | ||
}; | ||
} |
if (!String.prototype.includes) { | ||
String.prototype.includes = function(search, start) { | ||
if (typeof start !== 'number') { | ||
start = 0; | ||
} | ||
// eslint-disable-next-line no-extend-native | ||
String.prototype.includes = function (search, start) { | ||
if (typeof start !== "number") { | ||
start = 0; | ||
} | ||
if (start + search.length > this.length) { | ||
return false; | ||
} else { | ||
return this.indexOf(search, start) !== -1; | ||
} | ||
}; | ||
} | ||
if (start + search.length > this.length) { | ||
return false; | ||
} else { | ||
return this.indexOf(search, start) !== -1; | ||
} | ||
}; | ||
} |
import window from "./global/window"; | ||
import { checkAlternationMatch } from "./validation"; | ||
import { | ||
determineTestTemplate, | ||
getMaskTemplate, | ||
getPlaceholder, | ||
getTest, | ||
getTests, | ||
getTestTemplate | ||
determineTestTemplate, | ||
getMaskTemplate, | ||
getPlaceholder, | ||
getTest, | ||
getTests, | ||
getTestTemplate | ||
} from "./validation-tests"; | ||
import {checkAlternationMatch} from "./validation"; | ||
export { | ||
caret, | ||
determineLastRequiredPosition, | ||
determineNewCaretPosition, | ||
getBuffer, | ||
getBufferTemplate, | ||
getLastValidPosition, | ||
isMask, | ||
resetMaskSet, | ||
seekNext, | ||
seekPrevious, | ||
translatePosition | ||
caret, | ||
determineLastRequiredPosition, | ||
determineNewCaretPosition, | ||
getBuffer, | ||
getBufferTemplate, | ||
getLastValidPosition, | ||
isMask, | ||
resetMaskSet, | ||
seekNext, | ||
seekPrevious, | ||
translatePosition | ||
}; | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function caret(input, begin, end, notranslate, isDelete) { | ||
const inputmask = this, | ||
opts = this.opts; | ||
const inputmask = this, | ||
opts = this.opts; | ||
var range; | ||
if (begin !== undefined) { | ||
if (Array.isArray(begin)) { | ||
end = inputmask.isRTL ? begin[0] : begin[1]; | ||
begin = inputmask.isRTL ? begin[1] : begin[0]; | ||
} | ||
if (begin.begin !== undefined) { | ||
end = inputmask.isRTL ? begin.begin : begin.end; | ||
begin = inputmask.isRTL ? begin.end : begin.begin; | ||
} | ||
if (typeof begin === "number") { | ||
begin = notranslate ? begin : translatePosition.call(inputmask, begin); | ||
end = notranslate ? end : translatePosition.call(inputmask, end); | ||
end = (typeof end == "number") ? end : begin; | ||
// if (!$(input).is(":visible")) { | ||
// return; | ||
// } | ||
let range; | ||
if (begin !== undefined) { | ||
if (Array.isArray(begin)) { | ||
end = inputmask.isRTL ? begin[0] : begin[1]; | ||
begin = inputmask.isRTL ? begin[1] : begin[0]; | ||
} | ||
if (begin.begin !== undefined) { | ||
end = inputmask.isRTL ? begin.begin : begin.end; | ||
begin = inputmask.isRTL ? begin.end : begin.begin; | ||
} | ||
if (typeof begin === "number") { | ||
begin = notranslate ? begin : translatePosition.call(inputmask, begin); | ||
end = notranslate ? end : translatePosition.call(inputmask, end); | ||
end = typeof end === "number" ? end : begin; | ||
// if (!$(input).is(":visible")) { | ||
// return; | ||
// } | ||
var scrollCalc = parseInt(((input.ownerDocument.defaultView || window).getComputedStyle ? (input.ownerDocument.defaultView || window).getComputedStyle(input, null) : input.currentStyle).fontSize) * end; | ||
input.scrollLeft = scrollCalc > input.scrollWidth ? scrollCalc : 0; | ||
input.inputmask.caretPos = {begin: begin, end: end}; //track caret internally | ||
if (opts.insertModeVisual && opts.insertMode === false && begin === end) { | ||
if (!isDelete) { | ||
end++; //set visualization for insert/overwrite mode | ||
} | ||
} | ||
if (input === (input.inputmask.shadowRoot || input.ownerDocument).activeElement) { | ||
if ("setSelectionRange" in input) { | ||
input.setSelectionRange(begin, end); | ||
} else if (window.getSelection) { | ||
range = document.createRange(); | ||
if (input.firstChild === undefined || input.firstChild === null) { | ||
var textNode = document.createTextNode(""); | ||
input.appendChild(textNode); | ||
} | ||
range.setStart(input.firstChild, begin < input.inputmask._valueGet().length ? begin : input.inputmask._valueGet().length); | ||
range.setEnd(input.firstChild, end < input.inputmask._valueGet().length ? end : input.inputmask._valueGet().length); | ||
range.collapse(true); | ||
var sel = window.getSelection(); | ||
sel.removeAllRanges(); | ||
sel.addRange(range); | ||
//input.focus(); | ||
} else if (input.createTextRange) { | ||
range = input.createTextRange(); | ||
range.collapse(true); | ||
range.moveEnd("character", end); | ||
range.moveStart("character", begin); | ||
range.select(); | ||
} | ||
const scrollCalc = | ||
parseInt( | ||
((input.ownerDocument.defaultView || window).getComputedStyle | ||
? (input.ownerDocument.defaultView || window).getComputedStyle( | ||
input, | ||
null | ||
) | ||
: input.currentStyle | ||
).fontSize | ||
) * end; | ||
input.scrollLeft = scrollCalc > input.scrollWidth ? scrollCalc : 0; | ||
input.inputmask.caretPos = { begin, end }; // track caret internally | ||
if (opts.insertModeVisual && opts.insertMode === false && begin === end) { | ||
if (!isDelete) { | ||
end++; // set visualization for insert/overwrite mode | ||
} | ||
} | ||
if ( | ||
input === | ||
(input.inputmask.shadowRoot || input.ownerDocument).activeElement | ||
) { | ||
if ("setSelectionRange" in input) { | ||
input.setSelectionRange(begin, end); | ||
} else if (window.getSelection) { | ||
range = document.createRange(); | ||
if (input.firstChild === undefined || input.firstChild === null) { | ||
const textNode = document.createTextNode(""); | ||
input.appendChild(textNode); | ||
} | ||
range.setStart( | ||
input.firstChild, | ||
begin < input.inputmask._valueGet().length | ||
? begin | ||
: input.inputmask._valueGet().length | ||
); | ||
range.setEnd( | ||
input.firstChild, | ||
end < input.inputmask._valueGet().length | ||
? end | ||
: input.inputmask._valueGet().length | ||
); | ||
range.collapse(true); | ||
const sel = window.getSelection(); | ||
sel.removeAllRanges(); | ||
sel.addRange(range); | ||
// input.focus(); | ||
} else if (input.createTextRange) { | ||
range = input.createTextRange(); | ||
range.collapse(true); | ||
range.moveEnd("character", end); | ||
range.moveStart("character", begin); | ||
range.select(); | ||
} | ||
input.inputmask.caretHook === undefined || input.inputmask.caretHook.call(inputmask, {begin, end}); | ||
} | ||
} | ||
} else { | ||
if ("selectionStart" in input && "selectionEnd" in input) { | ||
begin = input.selectionStart; | ||
end = input.selectionEnd; | ||
} else if (window.getSelection) { | ||
range = window.getSelection().getRangeAt(0); | ||
if (range.commonAncestorContainer.parentNode === input || range.commonAncestorContainer === input) { | ||
begin = range.startOffset; | ||
end = range.endOffset; | ||
} | ||
} else if (document.selection && document.selection.createRange) { | ||
range = document.selection.createRange(); | ||
begin = 0 - range.duplicate().moveStart("character", -input.inputmask._valueGet().length); | ||
end = begin + range.text.length; | ||
} | ||
input.inputmask.caretHook === undefined || | ||
input.inputmask.caretHook.call(inputmask, { begin, end }); | ||
} | ||
} | ||
} else { | ||
if ("selectionStart" in input && "selectionEnd" in input) { | ||
begin = input.selectionStart; | ||
end = input.selectionEnd; | ||
} else if (window.getSelection) { | ||
range = window.getSelection().getRangeAt(0); | ||
if ( | ||
range.commonAncestorContainer.parentNode === input || | ||
range.commonAncestorContainer === input | ||
) { | ||
begin = range.startOffset; | ||
end = range.endOffset; | ||
} | ||
} else if (document.selection && document.selection.createRange) { | ||
range = document.selection.createRange(); | ||
begin = | ||
0 - | ||
range | ||
.duplicate() | ||
.moveStart("character", -input.inputmask._valueGet().length); | ||
end = begin + range.text.length; | ||
} | ||
// if (opts.insertModeVisual && opts.insertMode === false && begin === (end - 1)) end--; //correct caret for insert/overwrite mode | ||
// if (opts.insertModeVisual && opts.insertMode === false && begin === (end - 1)) end--; //correct caret for insert/overwrite mode | ||
/*eslint-disable consistent-return */ | ||
return { | ||
"begin": notranslate ? begin : translatePosition.call(inputmask, begin), | ||
"end": notranslate ? end : translatePosition.call(inputmask, end) | ||
}; | ||
/*eslint-enable consistent-return */ | ||
} | ||
/* eslint-disable consistent-return */ | ||
return { | ||
begin: notranslate ? begin : translatePosition.call(inputmask, begin), | ||
end: notranslate ? end : translatePosition.call(inputmask, end) | ||
}; | ||
/* eslint-enable consistent-return */ | ||
} | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function determineLastRequiredPosition(returnDefinition) { | ||
const inputmask = this, {maskset, dependencyLib: $} = inputmask; | ||
const inputmask = this, | ||
{ maskset, dependencyLib: $ } = inputmask, | ||
lvp = getLastValidPosition.call(inputmask), | ||
positions = {}, | ||
lvTest = maskset.validPositions[lvp], | ||
buffer = getMaskTemplate.call( | ||
inputmask, | ||
true, | ||
getLastValidPosition.call(inputmask), | ||
true, | ||
true | ||
); | ||
let bl = buffer.length, | ||
pos, | ||
ndxIntlzr = lvTest !== undefined ? lvTest.locator.slice() : undefined, | ||
testPos; | ||
for (pos = lvp + 1; pos < buffer.length; pos++) { | ||
testPos = getTestTemplate.call(inputmask, pos, ndxIntlzr, pos - 1); | ||
ndxIntlzr = testPos.locator.slice(); | ||
positions[pos] = $.extend(true, {}, testPos); | ||
} | ||
var buffer = getMaskTemplate.call(inputmask, true, getLastValidPosition.call(inputmask), true, true), | ||
bl = buffer.length, | ||
pos, lvp = getLastValidPosition.call(inputmask), | ||
positions = {}, | ||
lvTest = maskset.validPositions[lvp], | ||
ndxIntlzr = lvTest !== undefined ? lvTest.locator.slice() : undefined, | ||
testPos; | ||
for (pos = lvp + 1; pos < buffer.length; pos++) { | ||
testPos = getTestTemplate.call(inputmask, pos, ndxIntlzr, pos - 1); | ||
ndxIntlzr = testPos.locator.slice(); | ||
positions[pos] = $.extend(true, {}, testPos); | ||
} | ||
var lvTestAlt = lvTest && lvTest.alternation !== undefined ? lvTest.locator[lvTest.alternation] : undefined; | ||
for (pos = bl - 1; pos > lvp; pos--) { | ||
testPos = positions[pos]; | ||
if ((testPos.match.optionality || | ||
(testPos.match.optionalQuantifier && testPos.match.newBlockMarker) || | ||
(lvTestAlt && | ||
( | ||
(lvTestAlt !== positions[pos].locator[lvTest.alternation] && testPos.match.static != true) || | ||
(testPos.match.static === true && | ||
testPos.locator[lvTest.alternation] && | ||
checkAlternationMatch.call(inputmask, testPos.locator[lvTest.alternation].toString().split(","), lvTestAlt.toString().split(",")) && | ||
getTests.call(inputmask, pos)[0].def !== "") | ||
) | ||
)) && | ||
buffer[pos] === getPlaceholder.call(inputmask, pos, testPos.match)) { | ||
bl--; | ||
} else { | ||
break; | ||
} | ||
} | ||
return returnDefinition ? { | ||
"l": bl, | ||
"def": positions[bl] ? positions[bl].match : undefined | ||
} : bl; | ||
const lvTestAlt = | ||
lvTest && lvTest.alternation !== undefined | ||
? lvTest.locator[lvTest.alternation] | ||
: undefined; | ||
for (pos = bl - 1; pos > lvp; pos--) { | ||
testPos = positions[pos]; | ||
if ( | ||
(testPos.match.optionality || | ||
(testPos.match.optionalQuantifier && testPos.match.newBlockMarker) || | ||
(lvTestAlt && | ||
((lvTestAlt !== positions[pos].locator[lvTest.alternation] && | ||
testPos.match.static !== true) || | ||
(testPos.match.static === true && | ||
testPos.locator[lvTest.alternation] && | ||
checkAlternationMatch.call( | ||
inputmask, | ||
testPos.locator[lvTest.alternation].toString().split(","), | ||
lvTestAlt.toString().split(",") | ||
) && | ||
getTests.call(inputmask, pos)[0].def !== "")))) && | ||
buffer[pos] === getPlaceholder.call(inputmask, pos, testPos.match) | ||
) { | ||
bl--; | ||
} else { | ||
break; | ||
} | ||
} | ||
return returnDefinition | ||
? { | ||
l: bl, | ||
def: positions[bl] ? positions[bl].match : undefined | ||
} | ||
: bl; | ||
} | ||
//tobe put on prototype? | ||
function determineNewCaretPosition(selectedCaret, tabbed, positionCaretOnClick) { | ||
const inputmask = this, {maskset, opts} = inputmask; | ||
// tobe put on prototype? | ||
function determineNewCaretPosition( | ||
selectedCaret, | ||
tabbed, | ||
positionCaretOnClick | ||
) { | ||
const inputmask = this, | ||
{ maskset, opts } = inputmask; | ||
let clickPosition, lvclickPosition, lastPosition; | ||
function doRadixFocus(clickPos) { | ||
if (opts.radixPoint !== "" && opts.digits !== 0) { | ||
var vps = maskset.validPositions; | ||
if (vps[clickPos] === undefined || (vps[clickPos].input === getPlaceholder.call(inputmask, clickPos))) { | ||
if (clickPos < seekNext.call(inputmask, -1)) return true; | ||
var radixPos = getBuffer.call(inputmask).indexOf(opts.radixPoint); | ||
if (radixPos !== -1) { | ||
for (let vp = 0, vpl = vps.length; vp < vpl; vp++) { | ||
if (vps[vp] && radixPos < vp && vps[vp].input !== getPlaceholder.call(inputmask, vp)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
function doRadixFocus(clickPos) { | ||
if (opts.radixPoint !== "" && opts.digits !== 0) { | ||
const vps = maskset.validPositions; | ||
if (vps[clickPos] === undefined || vps[clickPos].input === undefined) { | ||
if (clickPos < seekNext.call(inputmask, -1)) return true; | ||
const radixPos = getBuffer.call(inputmask).indexOf(opts.radixPoint); | ||
if (radixPos !== -1) { | ||
for (let vp = 0, vpl = vps.length; vp < vpl; vp++) { | ||
if ( | ||
vps[vp] && | ||
radixPos < vp && | ||
vps[vp].input !== getPlaceholder.call(inputmask, vp) | ||
) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
if (tabbed) { | ||
if (inputmask.isRTL) { | ||
selectedCaret.end = selectedCaret.begin; | ||
} else { | ||
selectedCaret.begin = selectedCaret.end; | ||
} | ||
} | ||
if (selectedCaret.begin === selectedCaret.end) { | ||
positionCaretOnClick = positionCaretOnClick || opts.positionCaretOnClick; | ||
switch (positionCaretOnClick) { | ||
case "none": | ||
break; | ||
case "select": | ||
selectedCaret = {begin: 0, end: getBuffer.call(inputmask).length}; | ||
break; | ||
case "ignore": | ||
selectedCaret.end = selectedCaret.begin = seekNext.call(inputmask, getLastValidPosition.call(inputmask)); | ||
break; | ||
case "radixFocus": | ||
if (inputmask.clicked > 1 && maskset.validPositions.length == 0) | ||
break; | ||
if (doRadixFocus(selectedCaret.begin)) { | ||
var radixPos = getBuffer.call(inputmask).join("").indexOf(opts.radixPoint); | ||
selectedCaret.end = selectedCaret.begin = opts.numericInput ? seekNext.call(inputmask, radixPos) : radixPos; | ||
break; | ||
} //fallback to lvp | ||
// eslint-disable-next-line no-fallthrough | ||
default: //lvp: | ||
var clickPosition = selectedCaret.begin, | ||
lvclickPosition = getLastValidPosition.call(inputmask, clickPosition, true), | ||
lastPosition = seekNext.call(inputmask, (lvclickPosition === -1 && !isMask.call(inputmask, 0)) ? -1 : lvclickPosition); | ||
if (tabbed) { | ||
if (inputmask.isRTL) { | ||
selectedCaret.end = selectedCaret.begin; | ||
} else { | ||
selectedCaret.begin = selectedCaret.end; | ||
} | ||
} | ||
if (selectedCaret.begin === selectedCaret.end) { | ||
positionCaretOnClick = positionCaretOnClick || opts.positionCaretOnClick; | ||
switch (positionCaretOnClick) { | ||
case "none": | ||
break; | ||
case "select": | ||
selectedCaret = { begin: 0, end: getBuffer.call(inputmask).length }; | ||
break; | ||
case "ignore": | ||
selectedCaret.end = selectedCaret.begin = seekNext.call( | ||
inputmask, | ||
getLastValidPosition.call(inputmask) | ||
); | ||
break; | ||
case "radixFocus": | ||
if (inputmask.clicked > 1 && maskset.validPositions.length === 0) break; | ||
if (doRadixFocus(selectedCaret.begin)) { | ||
const radixPos = getBuffer | ||
.call(inputmask) | ||
.join("") | ||
.indexOf(opts.radixPoint); | ||
selectedCaret.end = selectedCaret.begin = opts.numericInput | ||
? seekNext.call(inputmask, radixPos) | ||
: radixPos; | ||
break; | ||
} // fallback to lvp | ||
// eslint-disable-next-line no-fallthrough | ||
default: // lvp: | ||
clickPosition = selectedCaret.begin; | ||
lvclickPosition = getLastValidPosition.call( | ||
inputmask, | ||
clickPosition, | ||
true | ||
); | ||
lastPosition = seekNext.call( | ||
inputmask, | ||
lvclickPosition === -1 && !isMask.call(inputmask, 0) | ||
? -1 | ||
: lvclickPosition | ||
); | ||
if (clickPosition <= lastPosition) { | ||
selectedCaret.end = selectedCaret.begin = !isMask.call(inputmask, clickPosition, false, true) ? seekNext.call(inputmask, clickPosition) : clickPosition; | ||
} else { | ||
var lvp = maskset.validPositions[lvclickPosition], | ||
tt = getTestTemplate.call(inputmask, lastPosition, lvp ? lvp.match.locator : undefined, lvp), | ||
placeholder = getPlaceholder.call(inputmask, lastPosition, tt.match); | ||
if ((placeholder !== "" && getBuffer.call(inputmask)[lastPosition] !== placeholder && tt.match.optionalQuantifier !== true && tt.match.newBlockMarker !== true) || (!isMask.call(inputmask, lastPosition, opts.keepStatic, true) && tt.match.def === placeholder)) { | ||
var newPos = seekNext.call(inputmask, lastPosition); | ||
if (clickPosition >= newPos || clickPosition === lastPosition) { | ||
lastPosition = newPos; | ||
} | ||
} | ||
selectedCaret.end = selectedCaret.begin = lastPosition; | ||
} | ||
} | ||
if (clickPosition <= lastPosition) { | ||
selectedCaret.end = selectedCaret.begin = !isMask.call( | ||
inputmask, | ||
clickPosition, | ||
false, | ||
true | ||
) | ||
? seekNext.call(inputmask, clickPosition) | ||
: clickPosition; | ||
} else { | ||
const lvp = maskset.validPositions[lvclickPosition], | ||
tt = getTestTemplate.call( | ||
inputmask, | ||
lastPosition, | ||
lvp ? lvp.match.locator : undefined, | ||
lvp | ||
), | ||
placeholder = getPlaceholder.call( | ||
inputmask, | ||
lastPosition, | ||
tt.match | ||
); | ||
if ( | ||
(placeholder !== "" && | ||
getBuffer.call(inputmask)[lastPosition] !== placeholder && | ||
tt.match.optionalQuantifier !== true && | ||
tt.match.newBlockMarker !== true) || | ||
(!isMask.call(inputmask, lastPosition, opts.keepStatic, true) && | ||
tt.match.def === placeholder) | ||
) { | ||
const newPos = seekNext.call(inputmask, lastPosition); | ||
if (clickPosition >= newPos || clickPosition === lastPosition) { | ||
lastPosition = newPos; | ||
} | ||
} | ||
selectedCaret.end = selectedCaret.begin = lastPosition; | ||
} | ||
} | ||
return selectedCaret; | ||
} | ||
return selectedCaret; | ||
} | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function getBuffer(noCache) { | ||
const inputmask = this, {maskset} = inputmask; | ||
const inputmask = this, | ||
{ maskset } = inputmask; | ||
if (maskset.buffer === undefined || noCache === true) { | ||
maskset.buffer = getMaskTemplate.call(inputmask, true, getLastValidPosition.call(inputmask), true); | ||
if (maskset._buffer === undefined) maskset._buffer = maskset.buffer.slice(); | ||
} | ||
return maskset.buffer; | ||
if (maskset.buffer === undefined || noCache === true) { | ||
maskset.buffer = getMaskTemplate.call( | ||
inputmask, | ||
true, | ||
getLastValidPosition.call(inputmask), | ||
true | ||
); | ||
if (maskset._buffer === undefined) maskset._buffer = maskset.buffer.slice(); | ||
} | ||
return maskset.buffer; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function getBufferTemplate() { | ||
const inputmask = this, maskset = this.maskset; | ||
const inputmask = this, | ||
maskset = this.maskset; | ||
if (maskset._buffer === undefined) { | ||
//generate template | ||
maskset._buffer = getMaskTemplate.call(inputmask, false, 1); | ||
if (maskset.buffer === undefined) maskset.buffer = maskset._buffer.slice(); | ||
} | ||
return maskset._buffer; | ||
if (maskset._buffer === undefined) { | ||
// generate template | ||
maskset._buffer = getMaskTemplate.call(inputmask, false, 1); | ||
if (maskset.buffer === undefined) maskset.buffer = maskset._buffer.slice(); | ||
} | ||
return maskset._buffer; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function getLastValidPosition(closestTo, strict, validPositions) { | ||
const maskset = this.maskset; | ||
const maskset = this.maskset; | ||
var before = -1, | ||
after = -1, | ||
valids = validPositions || maskset.validPositions; //for use in valhook ~ context switch | ||
if (closestTo === undefined) closestTo = -1; | ||
for (var psNdx = 0, vpl = valids.length; psNdx < vpl; psNdx++) { | ||
if (valids[psNdx] && (strict || valids[psNdx].generatedInput !== true)) { | ||
if (psNdx <= closestTo) before = psNdx; | ||
if (psNdx >= closestTo) after = psNdx; | ||
} | ||
} | ||
return (before === -1 || before == closestTo) ? after : after == -1 ? before : (closestTo - before) < (after - closestTo) ? before : after; | ||
let before = -1, | ||
after = -1; | ||
const valids = validPositions || maskset.validPositions; // for use in valhook ~ context switch | ||
if (closestTo === undefined) closestTo = -1; | ||
for (let psNdx = 0, vpl = valids.length; psNdx < vpl; psNdx++) { | ||
if (valids[psNdx] && (strict || valids[psNdx].generatedInput !== true)) { | ||
if (psNdx <= closestTo) before = psNdx; | ||
if (psNdx >= closestTo) after = psNdx; | ||
} | ||
} | ||
return before === -1 || before === closestTo | ||
? after | ||
: after === -1 | ||
? before | ||
: closestTo - before < after - closestTo | ||
? before | ||
: after; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function isMask(pos, strict, fuzzy) { | ||
const inputmask = this, maskset = this.maskset; | ||
const inputmask = this, | ||
maskset = this.maskset; | ||
var test = getTestTemplate.call(inputmask, pos).match; | ||
if (test.def === "") test = getTest.call(inputmask, pos).match; | ||
let test = getTestTemplate.call(inputmask, pos).match; | ||
if (test.def === "") test = getTest.call(inputmask, pos).match; | ||
if (test.static !== true) { | ||
return test.fn; | ||
} | ||
if (fuzzy === true && (maskset.validPositions[pos] !== undefined && maskset.validPositions[pos].generatedInput !== true)) { | ||
return true; | ||
} | ||
if (test.static !== true) { | ||
return test.fn; | ||
} | ||
if ( | ||
fuzzy === true && | ||
maskset.validPositions[pos] !== undefined && | ||
maskset.validPositions[pos].generatedInput !== true | ||
) { | ||
return true; | ||
} | ||
if (strict !== true && pos > -1) { | ||
if (fuzzy) { //check on the number of tests | ||
var tests = getTests.call(inputmask, pos); | ||
return tests.length > (1 + (tests[tests.length - 1].match.def === "" ? 1 : 0)); | ||
} | ||
//else based on the template | ||
var testTemplate = determineTestTemplate.call(inputmask, pos, getTests.call(inputmask, pos)); | ||
var testPlaceHolder = getPlaceholder.call(inputmask, pos, testTemplate.match); | ||
return testTemplate.match.def !== testPlaceHolder; | ||
} | ||
return false; | ||
if (strict !== true && pos > -1) { | ||
if (fuzzy) { | ||
// check on the number of tests | ||
const tests = getTests.call(inputmask, pos); | ||
return ( | ||
tests.length > 1 + (tests[tests.length - 1].match.def === "" ? 1 : 0) | ||
); | ||
} | ||
// else based on the template | ||
const testTemplate = determineTestTemplate.call( | ||
inputmask, | ||
pos, | ||
getTests.call(inputmask, pos) | ||
), | ||
testPlaceHolder = getPlaceholder.call(inputmask, pos, testTemplate.match); | ||
return testTemplate.match.def !== testPlaceHolder; | ||
} | ||
return false; | ||
} | ||
//tobe put on prototype? | ||
//soft ~ undefined reset validpositions; soft = false also reset tests; soft = true only reset the maskset | ||
// tobe put on prototype? | ||
// soft ~ undefined reset validpositions; soft = false also reset tests; soft = true only reset the maskset | ||
function resetMaskSet(soft) { | ||
const maskset = this.maskset; | ||
const maskset = this.maskset; | ||
maskset.buffer = undefined; | ||
if (soft !== true) { | ||
maskset.validPositions = []; | ||
maskset.p = 0; | ||
} | ||
if (soft === false) { | ||
maskset.tests = {}; | ||
} | ||
maskset.buffer = undefined; | ||
if (soft !== true) { | ||
maskset.validPositions = []; | ||
maskset.p = 0; | ||
} | ||
if (soft === false) { | ||
maskset.tests = {}; | ||
} | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function seekNext(pos, newBlock, fuzzy) { | ||
const inputmask = this; | ||
const inputmask = this; | ||
if (fuzzy === undefined) fuzzy = true; | ||
var position = pos + 1; | ||
while (getTest.call(inputmask, position).match.def !== "" && | ||
((newBlock === true && (getTest.call(inputmask, position).match.newBlockMarker !== true || !isMask.call(inputmask, position, undefined, true))) || | ||
(newBlock !== true && !isMask.call(inputmask, position, undefined, fuzzy)))) { | ||
position++; | ||
} | ||
return position; | ||
if (fuzzy === undefined) fuzzy = true; | ||
let position = pos + 1; | ||
while ( | ||
getTest.call(inputmask, position).match.def !== "" && | ||
((newBlock === true && | ||
(getTest.call(inputmask, position).match.newBlockMarker !== true || | ||
!isMask.call(inputmask, position, undefined, true))) || | ||
(newBlock !== true && | ||
!isMask.call(inputmask, position, undefined, fuzzy))) | ||
) { | ||
position++; | ||
} | ||
return position; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function seekPrevious(pos, newBlock) { | ||
const inputmask = this; | ||
const inputmask = this; | ||
var position = pos - 1; | ||
if (pos <= 0) return 0; | ||
let position = pos - 1; | ||
if (pos <= 0) return 0; | ||
while (position > 0 && | ||
((newBlock === true && (getTest.call(inputmask, position).match.newBlockMarker !== true || !isMask.call(inputmask, position, undefined, true))) || | ||
(newBlock !== true && !isMask.call(inputmask, position, undefined, true)))) { | ||
position--; | ||
} | ||
return position; | ||
while ( | ||
position > 0 && | ||
((newBlock === true && | ||
(getTest.call(inputmask, position).match.newBlockMarker !== true || | ||
!isMask.call(inputmask, position, undefined, true))) || | ||
(newBlock !== true && !isMask.call(inputmask, position, undefined, true))) | ||
) { | ||
position--; | ||
} | ||
return position; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function translatePosition(pos) { | ||
const inputmask = this, | ||
opts = this.opts, | ||
el = this.el; | ||
const inputmask = this, | ||
opts = this.opts, | ||
el = this.el; | ||
if (inputmask.isRTL && typeof pos === "number" && (!opts.greedy || opts.placeholder !== "") && el) { | ||
pos = inputmask._valueGet().length - pos; | ||
if (pos < 0) pos = 0; | ||
} | ||
return pos; | ||
if ( | ||
inputmask.isRTL && | ||
typeof pos === "number" && | ||
(!opts.greedy || opts.placeholder !== "") && | ||
el | ||
) { | ||
pos = inputmask._valueGet().length - pos; | ||
if (pos < 0) pos = 0; | ||
} | ||
return pos; | ||
} |
@@ -1,702 +0,1021 @@ | ||
import {getLastValidPosition, seekNext} from "./positioning"; | ||
import Inputmask from "./inputmask"; | ||
import { getLastValidPosition, seekNext } from "./positioning"; | ||
export { | ||
determineTestTemplate, | ||
getDecisionTaker, | ||
getMaskTemplate, | ||
getPlaceholder, | ||
getTest, | ||
getTests, | ||
getTestTemplate, | ||
isSubsetOf | ||
determineTestTemplate, | ||
getDecisionTaker, | ||
getMaskTemplate, | ||
getPlaceholder, | ||
getTest, | ||
getTests, | ||
getTestTemplate, | ||
isSubsetOf | ||
}; | ||
import Inputmask from "./inputmask"; | ||
function getLocator(tst, align) { //need to align the locators to be correct | ||
var 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 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) { | ||
var 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() : ""; | ||
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? | ||
// tobe put on prototype? | ||
function getPlaceholder(pos, test, returnPL) { | ||
const inputmask = this, | ||
opts = this.opts, | ||
maskset = this.maskset; | ||
const inputmask = this, | ||
opts = this.opts, | ||
maskset = this.maskset; | ||
test = test || getTest.call(inputmask, pos).match; | ||
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; | ||
} | ||
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); | ||
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 | ||
// tobe put on prototype? | ||
function getMaskTemplate( | ||
baseOnInput, | ||
minimalPos, | ||
includeMode, | ||
noJit, | ||
clearOptionalTail | ||
) { | ||
// includeMode true => input, undefined => placeholder, false => mask | ||
var inputmask = this, | ||
opts = this.opts, | ||
maskset = this.maskset; | ||
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; | ||
} | ||
} | ||
var greedy = opts.greedy; | ||
if (clearOptionalTail && opts.greedy) { | ||
opts.greedy = false; | ||
inputmask.maskset.tests = {}; | ||
} | ||
minimalPos = minimalPos || 0; | ||
var 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(); | ||
var 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; | ||
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; | ||
} | ||
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; | ||
opts.greedy = greedy; | ||
return maskTemplate; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function getTestTemplate(pos, ndxIntlzr, tstPs) { | ||
var inputmask = this, | ||
maskset = this.maskset; | ||
const inputmask = this, | ||
maskset = this.maskset; | ||
return maskset.validPositions[pos] || determineTestTemplate.call(inputmask, pos, getTests.call(inputmask, pos, ndxIntlzr ? ndxIntlzr.slice() : ndxIntlzr, tstPs)); | ||
return ( | ||
maskset.validPositions[pos] || | ||
determineTestTemplate.call( | ||
inputmask, | ||
pos, | ||
getTests.call( | ||
inputmask, | ||
pos, | ||
ndxIntlzr ? ndxIntlzr.slice() : ndxIntlzr, | ||
tstPs | ||
) | ||
) | ||
); | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function determineTestTemplate(pos, tests) { | ||
var inputmask = this, | ||
opts = this.opts, | ||
lenghtOffset = 0; | ||
var optionalityLevel = determineOptionalityLevel(pos, tests); | ||
pos = pos > 0 ? pos - 1 : 0; | ||
var 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 (var ndx = 0; ndx < tests.length - lenghtOffset; ndx++) { //find best matching | ||
var tst = tests[ndx]; | ||
tstLocator = getLocator(tst, targetLocator.length); | ||
var distance = Math.abs(tstLocator - targetLocator); | ||
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; | ||
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; | ||
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? | ||
// tobe put on prototype? | ||
function getTest(pos, tests) { | ||
var inputmask = this, | ||
maskset = this.maskset; | ||
const inputmask = this, | ||
maskset = this.maskset; | ||
if (maskset.validPositions[pos]) { | ||
return maskset.validPositions[pos]; | ||
} | ||
return (tests || getTests.call(inputmask, pos))[0]; | ||
if (maskset.validPositions[pos]) { | ||
return maskset.validPositions[pos]; | ||
} | ||
return (tests || getTests.call(inputmask, pos))[0]; | ||
} | ||
function isSubsetOf(source, target, opts) { | ||
function expand(pattern) { | ||
var expanded = [], start = -1, end; | ||
for (var 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(""); | ||
} | ||
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 (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; | ||
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? | ||
// tobe put on prototype? | ||
function getTests(pos, ndxIntlzr, tstPs) { | ||
var 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; | ||
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) { | ||
var 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; | ||
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; | ||
} | ||
return true; | ||
}); | ||
} | ||
return firstMatch; | ||
} | ||
function resolveNdxInitializer(pos, alternateNdx, targetAlternation) { | ||
var bestMatch, indexPos; | ||
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 | ||
} | ||
var 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; | ||
} | ||
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) { | ||
var bestMatchAltIndex = bestMatch.locator[bestMatch.alternation]; | ||
var locator = bestMatch.mloc[alternateNdx] || bestMatch.mloc[bestMatchAltIndex] || bestMatch.locator; | ||
if (locator[locator.length - 1].toString().indexOf(":") !== -1) { | ||
var 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; | ||
} | ||
} | ||
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; | ||
} | ||
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 || {}; | ||
var 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) { | ||
var offset = 0; | ||
for (var 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; | ||
} | ||
// 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; | ||
} | ||
var alternationNdx = targetMatch.alternation, | ||
shouldMerge = altMatch === undefined || (alternationNdx <= altMatch.alternation && | ||
targetMatch.locator[alternationNdx].toString().indexOf(altMatch.locator[alternationNdx]) === -1); | ||
if (!shouldMerge && alternationNdx > altMatch.alternation) { | ||
for (var i = 0; i < alternationNdx; i++) { | ||
if (targetMatch.locator[i] !== altMatch.locator[i]) { | ||
alternationNdx = i; | ||
shouldMerge = true; | ||
break; | ||
} | ||
} | ||
} | ||
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; | ||
} | ||
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 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 handleGroup() { | ||
match = handleMatch( | ||
maskToken.matches[maskToken.matches.indexOf(match) + 1], | ||
loopNdx, | ||
quantifierRecurse | ||
); | ||
if (match) return true; | ||
} | ||
function handleOptional() { | ||
var 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; | ||
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 | ||
} | ||
} | ||
} | ||
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; | ||
} | ||
} | ||
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; | ||
} | ||
return matchesLength !== matchesNewLength; | ||
} | ||
inputmask.hasAlternator = true; | ||
var alternateToken = match, | ||
malternateMatches = [], | ||
maltMatches, | ||
currentMatches = matches.slice(), | ||
loopNdxCnt = loopNdx.length; | ||
var altIndex = ndxInitializer.length > 0 ? ndxInitializer.shift() : -1; | ||
if (altIndex === -1 || typeof altIndex === "string") { | ||
var 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()); | ||
} | ||
} | ||
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) { | ||
var altIndexArrClone = altIndexArr.slice(); | ||
for (var i = 0, exl = maskset.excludes[pos].length; i < exl; i++) { | ||
var 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 (var 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); | ||
var 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; | ||
} | ||
} | ||
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 = []; | ||
maltMatches = matches.slice(); | ||
testPos = currentPos; | ||
matches = []; | ||
//fuzzy merge matches | ||
for (var ndx1 = 0; ndx1 < maltMatches.length; ndx1++) { | ||
var altMatch = maltMatches[ndx1], | ||
dropMatch = false; | ||
altMatch.alternation = altMatch.alternation || loopNdxCnt; | ||
setMergeLocators(altMatch); | ||
for (var ndx2 = 0; ndx2 < malternateMatches.length; ndx2++) { | ||
var 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); | ||
} | ||
} | ||
} | ||
// 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 | ||
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; | ||
}); | ||
} | ||
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; | ||
} | ||
// cloneback | ||
ndxInitializer = ndxInitializerClone.slice(); | ||
} else { | ||
match = handleMatch( | ||
alternateToken.matches[altIndex] || maskToken.matches[altIndex], | ||
[altIndex].concat(loopNdx), | ||
quantifierRecurse | ||
); | ||
} | ||
if (match) return true; | ||
} | ||
function handleQuantifier() { | ||
var 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; | ||
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; | ||
} | ||
} | ||
} | ||
// 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 "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": 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++; | ||
} | ||
} | ||
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 (var tndx = (ndxInitializer.length > 0 ? ndxInitializer.shift() : 0); tndx < maskToken.matches.length; tndx++) { | ||
if (maskToken.matches[tndx].isQuantifier !== true) { | ||
var match = handleMatch(maskToken.matches[tndx], [tndx].concat(loopNdx), quantifierRecurse); | ||
if (match && testPos === pos) { | ||
return match; | ||
} else if (testPos > pos) { | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
// 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 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]; | ||
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 (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 | ||
var 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 (var mtndx = ndxInitializer.shift(); mtndx < maskTokens.length; mtndx++) { | ||
var 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 | ||
}); | ||
} | ||
var 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]; | ||
} | ||
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; | ||
}); | ||
// console.log(pos + " - " + JSON.stringify(matches)); | ||
// cleanup optionality marking | ||
matches.forEach((t) => { | ||
t.match.optionality = t.match.defOptionality || false; | ||
}); | ||
return result; | ||
return result; | ||
} |
@@ -0,694 +1,1057 @@ | ||
import { EventHandlers } from "./eventhandlers"; | ||
import { keyCode, keys } from "./keycode.js"; | ||
import { | ||
determineTestTemplate, | ||
getDecisionTaker, | ||
getPlaceholder, | ||
getTest, | ||
getTests, | ||
getTestTemplate | ||
determineLastRequiredPosition, | ||
determineNewCaretPosition, | ||
getBuffer, | ||
getLastValidPosition, | ||
isMask, | ||
resetMaskSet, | ||
seekNext, | ||
seekPrevious | ||
} from "./positioning"; | ||
import { | ||
determineTestTemplate, | ||
getDecisionTaker, | ||
getPlaceholder, | ||
getTest, | ||
getTests, | ||
getTestTemplate | ||
} from "./validation-tests"; | ||
import {keyCode, keys} from "./keycode.js"; | ||
import { | ||
determineLastRequiredPosition, determineNewCaretPosition, | ||
getBuffer, | ||
getLastValidPosition, | ||
isMask, | ||
resetMaskSet, | ||
seekNext, | ||
seekPrevious | ||
} from "./positioning"; | ||
import {EventHandlers} from "./eventhandlers"; | ||
export { | ||
alternate, | ||
checkAlternationMatch, | ||
isComplete, | ||
isSelection, | ||
isValid, | ||
refreshFromBuffer, | ||
revalidateMask, | ||
handleRemove | ||
alternate, | ||
checkAlternationMatch, | ||
isComplete, | ||
isSelection, | ||
isValid, | ||
refreshFromBuffer, | ||
revalidateMask, | ||
handleRemove | ||
}; | ||
//tobe put on prototype? | ||
function alternate(maskPos, c, strict, fromIsValid, rAltPos, selection) { //pos == true => generalize | ||
const inputmask = this, | ||
$ = this.dependencyLib, | ||
opts = this.opts, | ||
maskset = inputmask.maskset; | ||
// tobe put on prototype? | ||
function alternate(maskPos, c, strict, fromIsValid, rAltPos, selection) { | ||
// pos == true => generalize | ||
const inputmask = this, | ||
$ = this.dependencyLib, | ||
opts = this.opts, | ||
maskset = inputmask.maskset; | ||
var validPsClone = $.extend(true, [], maskset.validPositions), | ||
tstClone = $.extend(true, {}, maskset.tests), | ||
lastAlt, | ||
alternation, | ||
isValidRslt = false, returnRslt = false, | ||
altPos, prevAltPos, i, validPos, | ||
decisionPos, | ||
lAltPos = rAltPos !== undefined ? rAltPos : getLastValidPosition.call(inputmask), nextPos, input, begin, end; | ||
if (!inputmask.hasAlternator) return false; | ||
if (selection) { | ||
begin = selection.begin; | ||
end = selection.end; | ||
if (selection.begin > selection.end) { | ||
begin = selection.end; | ||
end = selection.begin; | ||
} | ||
} | ||
if (lAltPos === -1 && rAltPos === undefined) { //do not recurse when already paste the beginning | ||
lastAlt = 0; | ||
prevAltPos = getTest.call(inputmask, lastAlt); | ||
alternation = prevAltPos.alternation; | ||
} else { | ||
//find last modified alternation | ||
for (; lAltPos >= 0; lAltPos--) { | ||
altPos = maskset.validPositions[lAltPos]; | ||
if (altPos && altPos.alternation !== undefined) { | ||
if (lAltPos <= (maskPos || 0) && prevAltPos && prevAltPos.locator[altPos.alternation] !== altPos.locator[altPos.alternation]) { | ||
break; | ||
} | ||
lastAlt = lAltPos; | ||
alternation = maskset.validPositions[lastAlt].alternation; | ||
prevAltPos = altPos; | ||
} | ||
} | ||
} | ||
let validPsClone = $.extend(true, [], maskset.validPositions), | ||
tstClone = $.extend(true, {}, maskset.tests), | ||
lastAlt, | ||
alternation, | ||
isValidRslt = false, | ||
returnRslt = false, | ||
altPos, | ||
prevAltPos, | ||
i, | ||
validPos, | ||
decisionPos, | ||
lAltPos = | ||
rAltPos !== undefined ? rAltPos : getLastValidPosition.call(inputmask), | ||
nextPos, | ||
input, | ||
begin, | ||
end; | ||
if (alternation !== undefined) { | ||
decisionPos = parseInt(lastAlt); | ||
maskset.excludes[decisionPos] = maskset.excludes[decisionPos] || []; | ||
if (maskPos !== true) { //generalize | ||
maskset.excludes[decisionPos].push(getDecisionTaker(prevAltPos) + ":" + prevAltPos.alternation); | ||
} | ||
if (selection) { | ||
begin = selection.begin; | ||
end = selection.end; | ||
if (selection.begin > selection.end) { | ||
begin = selection.end; | ||
end = selection.begin; | ||
} | ||
} | ||
if (lAltPos === -1 && rAltPos === undefined) { | ||
// do not recurse when already paste the beginning | ||
lastAlt = 0; | ||
prevAltPos = getTest.call(inputmask, lastAlt); | ||
alternation = prevAltPos.alternation; | ||
} else { | ||
// find last modified alternation | ||
for (; lAltPos >= 0; lAltPos--) { | ||
altPos = maskset.validPositions[lAltPos]; | ||
if (altPos && altPos.alternation !== undefined) { | ||
if ( | ||
lAltPos <= (maskPos || 0) && | ||
prevAltPos && | ||
prevAltPos.locator[altPos.alternation] !== | ||
altPos.locator[altPos.alternation] | ||
) { | ||
break; | ||
} | ||
lastAlt = lAltPos; | ||
alternation = maskset.validPositions[lastAlt].alternation; | ||
prevAltPos = altPos; | ||
} | ||
} | ||
} | ||
var validInputs = [], resultPos = -1; | ||
for (i = decisionPos; decisionPos < getLastValidPosition.call(inputmask, undefined, true) + 1; i++) { | ||
if (resultPos === -1 && maskPos <= i && c !== undefined) { | ||
validInputs.push(c); | ||
resultPos = validInputs.length - 1; | ||
} | ||
validPos = maskset.validPositions[decisionPos]; | ||
if (validPos && validPos.generatedInput !== true && (selection === undefined || (i < begin || i >= end))) { | ||
validInputs.push(validPos.input); | ||
} | ||
// delete maskset.validPositions[i++]; | ||
maskset.validPositions.splice(decisionPos, 1); | ||
} | ||
if (resultPos === -1 && c !== undefined) { | ||
validInputs.push(c); | ||
resultPos = validInputs.length - 1; | ||
} | ||
if (alternation !== undefined) { | ||
decisionPos = parseInt(lastAlt); | ||
maskset.excludes[decisionPos] = maskset.excludes[decisionPos] || []; | ||
if (maskPos !== true) { | ||
// generalize | ||
maskset.excludes[decisionPos].push( | ||
getDecisionTaker(prevAltPos) + ":" + prevAltPos.alternation | ||
); | ||
} | ||
while (maskset.excludes[decisionPos] !== undefined && maskset.excludes[decisionPos].length < 10) { | ||
// maskset.tests[decisionPos] = undefined; //clear decisionPos | ||
maskset.tests = {}; //clear all | ||
resetMaskSet.call(inputmask, true); //clear getbuffer | ||
isValidRslt = true; | ||
for (i = 0; i < validInputs.length; i++) { | ||
nextPos = isValidRslt.caret || opts.insertMode == false && nextPos != undefined ? seekNext.call(inputmask, nextPos) : (getLastValidPosition.call(inputmask, undefined, true) + 1); | ||
input = validInputs[i]; | ||
// nextPos = translatePosition.call(inputmask, nextPos); | ||
if (!(isValidRslt = isValid.call(inputmask, nextPos, input, false, fromIsValid, true))) { | ||
break; | ||
} | ||
if (i === resultPos) { | ||
returnRslt = isValidRslt; | ||
} | ||
if (maskPos == true && isValidRslt) { //return validposition on generalise | ||
returnRslt = {caretPos: i}; | ||
} | ||
} | ||
if (!isValidRslt) { | ||
resetMaskSet.call(inputmask); | ||
prevAltPos = getTest.call(inputmask, decisionPos); //get the current decisionPos to exclude ~ needs to be before restoring the initial validation | ||
//reset & revert | ||
maskset.validPositions = $.extend(true, [], validPsClone); | ||
maskset.tests = $.extend(true, {}, tstClone); //refresh tests after possible alternating | ||
if (maskset.excludes[decisionPos]) { | ||
if (prevAltPos.alternation != undefined) { | ||
var decisionTaker = getDecisionTaker(prevAltPos); | ||
if (maskset.excludes[decisionPos].indexOf(decisionTaker + ":" + prevAltPos.alternation) !== -1) { | ||
returnRslt = alternate.call(inputmask, maskPos, c, strict, fromIsValid, decisionPos - 1, selection); | ||
break; | ||
} | ||
maskset.excludes[decisionPos].push(decisionTaker + ":" + prevAltPos.alternation); | ||
for (i = decisionPos; i < getLastValidPosition.call(inputmask, undefined, true) + 1; i++) maskset.validPositions.splice(decisionPos); | ||
} else | ||
delete maskset.excludes[decisionPos]; | ||
} else { //latest alternation | ||
returnRslt = alternate.call(inputmask, maskPos, c, strict, fromIsValid, decisionPos - 1, selection); | ||
break; | ||
} | ||
} else { | ||
break; | ||
} | ||
} | ||
} | ||
let validInputs = [], | ||
resultPos = -1; | ||
for ( | ||
i = decisionPos; | ||
decisionPos < getLastValidPosition.call(inputmask, undefined, true) + 1; | ||
i++ | ||
) { | ||
if (resultPos === -1 && maskPos <= i && c !== undefined) { | ||
validInputs.push(c); | ||
resultPos = validInputs.length - 1; | ||
} | ||
validPos = maskset.validPositions[decisionPos]; | ||
if ( | ||
validPos && | ||
validPos.generatedInput !== true && | ||
(selection === undefined || i < begin || i >= end) | ||
) { | ||
validInputs.push(validPos.input); | ||
} | ||
// delete maskset.validPositions[i++]; | ||
maskset.validPositions.splice(decisionPos, 1); | ||
} | ||
if (resultPos === -1 && c !== undefined) { | ||
validInputs.push(c); | ||
resultPos = validInputs.length - 1; | ||
} | ||
//reset alternation excludes | ||
if (!returnRslt || opts.keepStatic !== false) { | ||
delete maskset.excludes[decisionPos]; | ||
} | ||
return returnRslt; | ||
while ( | ||
maskset.excludes[decisionPos] !== undefined && | ||
maskset.excludes[decisionPos].length < 10 | ||
) { | ||
// maskset.tests[decisionPos] = undefined; //clear decisionPos | ||
maskset.tests = {}; // clear all | ||
resetMaskSet.call(inputmask, true); // clear getbuffer | ||
isValidRslt = true; | ||
for (i = 0; i < validInputs.length; i++) { | ||
nextPos = | ||
isValidRslt.caret || | ||
(opts.insertMode == false && nextPos != undefined) | ||
? seekNext.call(inputmask, nextPos) | ||
: getLastValidPosition.call(inputmask, undefined, true) + 1; | ||
input = validInputs[i]; | ||
// nextPos = translatePosition.call(inputmask, nextPos); | ||
if ( | ||
!(isValidRslt = isValid.call( | ||
inputmask, | ||
nextPos, | ||
input, | ||
false, | ||
fromIsValid, | ||
true | ||
)) | ||
) { | ||
break; | ||
} | ||
if (i === resultPos) { | ||
returnRslt = isValidRslt; | ||
} | ||
if (maskPos == true && isValidRslt) { | ||
// return validposition on generalise | ||
returnRslt = { caretPos: i }; | ||
} | ||
} | ||
if (!isValidRslt) { | ||
resetMaskSet.call(inputmask); | ||
prevAltPos = getTest.call(inputmask, decisionPos); // get the current decisionPos to exclude ~ needs to be before restoring the initial validation | ||
// reset & revert | ||
maskset.validPositions = $.extend(true, [], validPsClone); | ||
maskset.tests = $.extend(true, {}, tstClone); // refresh tests after possible alternating | ||
if (maskset.excludes[decisionPos]) { | ||
if (prevAltPos.alternation != undefined) { | ||
const decisionTaker = getDecisionTaker(prevAltPos); | ||
if ( | ||
maskset.excludes[decisionPos].indexOf( | ||
decisionTaker + ":" + prevAltPos.alternation | ||
) !== -1 | ||
) { | ||
returnRslt = alternate.call( | ||
inputmask, | ||
maskPos, | ||
c, | ||
strict, | ||
fromIsValid, | ||
decisionPos - 1, | ||
selection | ||
); | ||
break; | ||
} | ||
maskset.excludes[decisionPos].push( | ||
decisionTaker + ":" + prevAltPos.alternation | ||
); | ||
for ( | ||
i = decisionPos; | ||
i < getLastValidPosition.call(inputmask, undefined, true) + 1; | ||
i++ | ||
) | ||
maskset.validPositions.splice(decisionPos); | ||
} else delete maskset.excludes[decisionPos]; | ||
} else { | ||
// latest alternation | ||
returnRslt = alternate.call( | ||
inputmask, | ||
maskPos, | ||
c, | ||
strict, | ||
fromIsValid, | ||
decisionPos - 1, | ||
selection | ||
); | ||
break; | ||
} | ||
} else { | ||
break; | ||
} | ||
} | ||
} | ||
// reset alternation excludes | ||
if (!returnRslt || opts.keepStatic !== false) { | ||
delete maskset.excludes[decisionPos]; | ||
} | ||
return returnRslt; | ||
} | ||
function casing(elem, test, pos) { | ||
const opts = this.opts, | ||
maskset = this.maskset; | ||
const opts = this.opts, | ||
maskset = this.maskset; | ||
switch (opts.casing || test.casing) { | ||
case "upper": | ||
elem = elem.toUpperCase(); | ||
break; | ||
case "lower": | ||
elem = elem.toLowerCase(); | ||
break; | ||
case "title": | ||
var posBefore = maskset.validPositions[pos - 1]; | ||
if (pos === 0 || posBefore && posBefore.input === String.fromCharCode(keyCode.Space)) { | ||
elem = elem.toUpperCase(); | ||
} else { | ||
elem = elem.toLowerCase(); | ||
} | ||
break; | ||
default: | ||
if (typeof opts.casing === "function") { | ||
var args = Array.prototype.slice.call(arguments); | ||
args.push(maskset.validPositions); | ||
elem = opts.casing.apply(this, args); | ||
} | ||
} | ||
switch (opts.casing || test.casing) { | ||
case "upper": | ||
elem = elem.toUpperCase(); | ||
break; | ||
case "lower": | ||
elem = elem.toLowerCase(); | ||
break; | ||
case "title": | ||
var posBefore = maskset.validPositions[pos - 1]; | ||
if ( | ||
pos === 0 || | ||
(posBefore && posBefore.input === String.fromCharCode(keyCode.Space)) | ||
) { | ||
elem = elem.toUpperCase(); | ||
} else { | ||
elem = elem.toLowerCase(); | ||
} | ||
break; | ||
default: | ||
if (typeof opts.casing === "function") { | ||
const args = Array.prototype.slice.call(arguments); | ||
args.push(maskset.validPositions); | ||
elem = opts.casing.apply(this, args); | ||
} | ||
} | ||
return elem; | ||
return elem; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function checkAlternationMatch(altArr1, altArr2, na) { | ||
const opts = this.opts; | ||
const opts = this.opts; | ||
var altArrC = opts.greedy ? altArr2 : altArr2.slice(0, 1), | ||
isMatch = false, | ||
naArr = na !== undefined ? na.split(",") : [], | ||
naNdx; | ||
let altArrC = opts.greedy ? altArr2 : altArr2.slice(0, 1), | ||
isMatch = false, | ||
naArr = na !== undefined ? na.split(",") : [], | ||
naNdx; | ||
//remove no alternate indexes from alternation array | ||
for (var i = 0; i < naArr.length; i++) { | ||
if ((naNdx = altArr1.indexOf(naArr[i])) !== -1) { | ||
altArr1.splice(naNdx, 1); | ||
} | ||
} | ||
// remove no alternate indexes from alternation array | ||
for (let i = 0; i < naArr.length; i++) { | ||
if ((naNdx = altArr1.indexOf(naArr[i])) !== -1) { | ||
altArr1.splice(naNdx, 1); | ||
} | ||
} | ||
for (var alndx = 0; alndx < altArr1.length; alndx++) { | ||
if (altArrC.includes(altArr1[alndx])) { | ||
isMatch = true; | ||
break; | ||
} | ||
} | ||
return isMatch; | ||
for (let alndx = 0; alndx < altArr1.length; alndx++) { | ||
if (altArrC.includes(altArr1[alndx])) { | ||
isMatch = true; | ||
break; | ||
} | ||
} | ||
return isMatch; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function handleRemove(input, c, pos, strict, fromIsValid) { | ||
const inputmask = this, maskset = this.maskset, opts = this.opts; | ||
const inputmask = this, | ||
maskset = this.maskset, | ||
opts = this.opts; | ||
if (opts.numericInput || inputmask.isRTL) { | ||
if (c === keys.Backspace) { | ||
c = keys.Delete; | ||
} else if (c === keys.Delete) { | ||
c = keys.Backspace; | ||
} | ||
if (opts.numericInput || inputmask.isRTL) { | ||
if (c === keys.Backspace) { | ||
c = keys.Delete; | ||
} else if (c === keys.Delete) { | ||
c = keys.Backspace; | ||
} | ||
if (inputmask.isRTL) { | ||
var pend = pos.end; | ||
pos.end = pos.begin; | ||
pos.begin = pend; | ||
} | ||
} | ||
if (inputmask.isRTL) { | ||
const pend = pos.end; | ||
pos.end = pos.begin; | ||
pos.begin = pend; | ||
} | ||
} | ||
var lvp = getLastValidPosition.call(inputmask, undefined, true); | ||
if (pos.end >= getBuffer.call(inputmask).length && lvp >= pos.end) { //handle numeric negate symbol offset, due to dynamic jit masking | ||
pos.end = lvp + 1; | ||
} | ||
const lvp = getLastValidPosition.call(inputmask, undefined, true); | ||
if (pos.end >= getBuffer.call(inputmask).length && lvp >= pos.end) { | ||
// handle numeric negate symbol offset, due to dynamic jit masking | ||
pos.end = lvp + 1; | ||
} | ||
if (c === keys.Backspace) { | ||
if ((pos.end - pos.begin < 1)) { | ||
pos.begin = seekPrevious.call(inputmask, pos.begin); | ||
} | ||
} else if (c === keys.Delete) { | ||
if (pos.begin === pos.end) { | ||
pos.end = isMask.call(inputmask, pos.end, true, true) ? pos.end + 1 : seekNext.call(inputmask, pos.end) + 1; | ||
} | ||
} | ||
var offset; | ||
if ((offset = revalidateMask.call(inputmask, pos)) !== false) { | ||
if (strict !== true && opts.keepStatic !== false || (opts.regex !== null && getTest.call(inputmask, pos.begin).match.def.indexOf("|") !== -1)) { //TODO NEEDS BETTER CHECK WHEN TO ALTERNATE ~ opts regex isn"t good enough | ||
var result = alternate.call(inputmask, true); | ||
if (result) { | ||
var newPos = result.caret !== undefined ? result.caret : (result.pos ? seekNext.call(inputmask, result.pos.begin ? result.pos.begin : result.pos) : getLastValidPosition.call(inputmask, -1, true)); | ||
if (c !== keys.Delete || pos.begin > newPos) { | ||
pos.begin == newPos; | ||
} | ||
} | ||
} | ||
if (c === keys.Backspace) { | ||
if (pos.end - pos.begin < 1) { | ||
pos.begin = seekPrevious.call(inputmask, pos.begin); | ||
} | ||
} else if (c === keys.Delete) { | ||
if (pos.begin === pos.end) { | ||
pos.end = isMask.call(inputmask, pos.end, true, true) | ||
? pos.end + 1 | ||
: seekNext.call(inputmask, pos.end) + 1; | ||
} | ||
} | ||
let offset; | ||
if ((offset = revalidateMask.call(inputmask, pos)) !== false) { | ||
if ( | ||
(strict !== true && opts.keepStatic !== false) || | ||
(opts.regex !== null && | ||
getTest.call(inputmask, pos.begin).match.def.indexOf("|") !== -1) | ||
) { | ||
// TODO NEEDS BETTER CHECK WHEN TO ALTERNATE ~ opts regex isn"t good enough | ||
alternate.call(inputmask, true); | ||
} | ||
if (strict !== true) { | ||
maskset.p = c === keys.Delete ? pos.begin + offset : pos.begin; | ||
maskset.p = determineNewCaretPosition.call(inputmask, { | ||
begin: maskset.p, | ||
end: maskset.p | ||
}, false, opts.insertMode === false && c === keys.Backspace ? "none" : undefined).begin; | ||
} | ||
} | ||
if (strict !== true) { | ||
maskset.p = c === keys.Delete ? pos.begin + offset : pos.begin; | ||
maskset.p = determineNewCaretPosition.call( | ||
inputmask, | ||
{ | ||
begin: maskset.p, | ||
end: maskset.p | ||
}, | ||
false, | ||
opts.insertMode === false && c === keys.Backspace ? "none" : undefined | ||
).begin; | ||
} | ||
} | ||
} | ||
//tobe put on prototype? | ||
function isComplete(buffer) { //return true / false / undefined (repeat *) | ||
const inputmask = this, opts = this.opts, maskset = this.maskset; | ||
// tobe put on prototype? | ||
function isComplete(buffer) { | ||
// return true / false / undefined (repeat *) | ||
const inputmask = this, | ||
opts = this.opts, | ||
maskset = this.maskset; | ||
if (typeof opts.isComplete === "function") return opts.isComplete(buffer, opts); | ||
if (opts.repeat === "*") return undefined; | ||
var complete = false, | ||
lrp = determineLastRequiredPosition.call(inputmask, true), | ||
aml = lrp.l; // seekPrevious.call(inputmask, lrp.l); | ||
if (typeof opts.isComplete === "function") | ||
return opts.isComplete(buffer, opts); | ||
if (opts.repeat === "*") return undefined; | ||
let complete = false, | ||
lrp = determineLastRequiredPosition.call(inputmask, true), | ||
aml = lrp.l; // seekPrevious.call(inputmask, lrp.l); | ||
if (lrp.def === undefined || lrp.def.newBlockMarker || lrp.def.optionality || lrp.def.optionalQuantifier) { | ||
complete = true; | ||
for (var i = 0; i <= aml; i++) { | ||
var test = getTestTemplate.call(inputmask, i).match; | ||
if ((test.static !== true && | ||
maskset.validPositions[i] === undefined && | ||
(test.optionality === false || test.optionality === undefined || (test.optionality && test.newBlockMarker == false)) && | ||
(test.optionalQuantifier === false || test.optionalQuantifier === undefined)) || | ||
(test.static === true && test.def != "" && buffer[i] !== getPlaceholder.call(inputmask, i, test)) | ||
) { | ||
complete = false; | ||
break; | ||
} | ||
} | ||
} | ||
if ( | ||
lrp.def === undefined || | ||
lrp.def.newBlockMarker || | ||
lrp.def.optionality || | ||
lrp.def.optionalQuantifier | ||
) { | ||
complete = true; | ||
for (let i = 0; i <= aml; i++) { | ||
const test = getTestTemplate.call(inputmask, i).match; | ||
if ( | ||
(test.static !== true && | ||
maskset.validPositions[i] === undefined && | ||
(test.optionality === false || | ||
test.optionality === undefined || | ||
(test.optionality && test.newBlockMarker == false)) && | ||
(test.optionalQuantifier === false || | ||
test.optionalQuantifier === undefined)) || | ||
(test.static === true && | ||
test.def != "" && | ||
buffer[i] !== getPlaceholder.call(inputmask, i, test)) | ||
) { | ||
complete = false; | ||
break; | ||
} | ||
} | ||
} | ||
return complete; | ||
return complete; | ||
} | ||
function isSelection(posObj) { | ||
const inputmask = this, | ||
opts = this.opts, insertModeOffset = opts.insertMode ? 0 : 1; | ||
return inputmask.isRTL ? (posObj.begin - posObj.end) > insertModeOffset : (posObj.end - posObj.begin) > insertModeOffset; | ||
const inputmask = this, | ||
opts = this.opts, | ||
insertModeOffset = opts.insertMode ? 0 : 1; | ||
return inputmask.isRTL | ||
? posObj.begin - posObj.end > insertModeOffset | ||
: posObj.end - posObj.begin > insertModeOffset; | ||
} | ||
//tobe put on prototype? | ||
function isValid(pos, c, strict, fromIsValid, fromAlternate, validateOnly, fromCheckval) { //strict true ~ no correction or autofill | ||
const inputmask = this, | ||
$ = this.dependencyLib, | ||
opts = this.opts, | ||
maskset = inputmask.maskset; | ||
// tobe put on prototype? | ||
function isValid( | ||
pos, | ||
c, | ||
strict, | ||
fromIsValid, | ||
fromAlternate, | ||
validateOnly, | ||
fromCheckval | ||
) { | ||
// strict true ~ no correction or autofill | ||
const inputmask = this, | ||
$ = this.dependencyLib, | ||
opts = this.opts, | ||
maskset = inputmask.maskset; | ||
strict = strict === true; //always set a value to strict to prevent possible strange behavior in the extensions | ||
strict = strict === true; // always set a value to strict to prevent possible strange behavior in the extensions | ||
var maskPos = pos; | ||
if (pos.begin !== undefined) { //position was a position object - used to handle a delete by typing over a selection | ||
maskPos = inputmask.isRTL ? pos.end : pos.begin; | ||
} | ||
let maskPos = pos; | ||
if (pos.begin !== undefined) { | ||
// position was a position object - used to handle a delete by typing over a selection | ||
maskPos = inputmask.isRTL ? pos.end : pos.begin; | ||
} | ||
function processCommandObject(commandObj) { | ||
if (commandObj !== undefined) { | ||
if (commandObj.remove !== undefined) { //remove position(s) | ||
if (!Array.isArray(commandObj.remove)) commandObj.remove = [commandObj.remove]; | ||
commandObj.remove.sort(function (a, b) { | ||
return inputmask.isRTL ? a.pos - b.pos : b.pos - a.pos; | ||
}).forEach(function (lmnt) { | ||
revalidateMask.call(inputmask, {begin: lmnt, end: lmnt + 1}); | ||
}); | ||
commandObj.remove = undefined; | ||
} | ||
if (commandObj.insert !== undefined) { //insert position(s) | ||
if (!Array.isArray(commandObj.insert)) commandObj.insert = [commandObj.insert]; | ||
commandObj.insert.sort(function (a, b) { | ||
return inputmask.isRTL ? b.pos - a.pos : a.pos - b.pos; | ||
}).forEach(function (lmnt) { | ||
if (lmnt.c !== "") { | ||
isValid.call(inputmask, lmnt.pos, lmnt.c, lmnt.strict !== undefined ? lmnt.strict : true, lmnt.fromIsValid !== undefined ? lmnt.fromIsValid : fromIsValid); | ||
} | ||
}); | ||
commandObj.insert = undefined; | ||
} | ||
function processCommandObject(commandObj) { | ||
if (commandObj !== undefined) { | ||
if (commandObj.remove !== undefined) { | ||
// remove position(s) | ||
if (!Array.isArray(commandObj.remove)) | ||
commandObj.remove = [commandObj.remove]; | ||
commandObj.remove | ||
.sort(function (a, b) { | ||
return inputmask.isRTL ? a.pos - b.pos : b.pos - a.pos; | ||
}) | ||
.forEach(function (lmnt) { | ||
revalidateMask.call(inputmask, { begin: lmnt, end: lmnt + 1 }); | ||
}); | ||
commandObj.remove = undefined; | ||
} | ||
if (commandObj.insert !== undefined) { | ||
// insert position(s) | ||
if (!Array.isArray(commandObj.insert)) | ||
commandObj.insert = [commandObj.insert]; | ||
commandObj.insert | ||
.sort(function (a, b) { | ||
return inputmask.isRTL ? b.pos - a.pos : a.pos - b.pos; | ||
}) | ||
.forEach(function (lmnt) { | ||
if (lmnt.c !== "") { | ||
isValid.call( | ||
inputmask, | ||
lmnt.pos, | ||
lmnt.c, | ||
lmnt.strict !== undefined ? lmnt.strict : true, | ||
lmnt.fromIsValid !== undefined ? lmnt.fromIsValid : fromIsValid | ||
); | ||
} | ||
}); | ||
commandObj.insert = undefined; | ||
} | ||
if (commandObj.refreshFromBuffer && commandObj.buffer) { | ||
var refresh = commandObj.refreshFromBuffer; | ||
refreshFromBuffer.call(inputmask, refresh === true ? refresh : refresh.start, refresh.end, commandObj.buffer); | ||
commandObj.refreshFromBuffer = undefined; | ||
} | ||
if (commandObj.refreshFromBuffer && commandObj.buffer) { | ||
const refresh = commandObj.refreshFromBuffer; | ||
refreshFromBuffer.call( | ||
inputmask, | ||
refresh === true ? refresh : refresh.start, | ||
refresh.end, | ||
commandObj.buffer | ||
); | ||
commandObj.refreshFromBuffer = undefined; | ||
} | ||
if (commandObj.rewritePosition !== undefined) { | ||
maskPos = commandObj.rewritePosition; | ||
// commandObj.rewritePosition = undefined; | ||
commandObj = true; // see prevalidation in isValid | ||
} | ||
} | ||
return commandObj; | ||
} | ||
if (commandObj.rewritePosition !== undefined) { | ||
maskPos = commandObj.rewritePosition; | ||
// commandObj.rewritePosition = undefined; | ||
commandObj = true; // see prevalidation in isValid | ||
} | ||
} | ||
return commandObj; | ||
} | ||
function _isValid(position, c, strict) { | ||
var rslt = false; | ||
getTests.call(inputmask, position).every(function (tst, ndx) { | ||
var test = tst.match; | ||
//make sure the buffer is set and correct | ||
getBuffer.call(inputmask, true); | ||
if (test.jit && maskset.validPositions[seekPrevious.call(inputmask, position)] === undefined) //ignore if jit is not desirable | ||
{ | ||
rslt = false; | ||
} else { | ||
//return is false or a json object => { pos: ??, c: ??} or true | ||
rslt = test.fn != null ? | ||
test.fn.test(c, maskset, position, strict, opts, isSelection.call(inputmask, pos)) : (c === test.def || c === opts.skipOptionalPartCharacter) && test.def !== "" ? //non mask | ||
{ | ||
c: getPlaceholder.call(inputmask, position, test, true) || test.def, | ||
pos: position | ||
} : false; | ||
} | ||
if (rslt !== false) { | ||
var elem = rslt.c !== undefined ? rslt.c : c, validatedPos = position; | ||
elem = (elem === opts.skipOptionalPartCharacter && test.static === true) ? | ||
(getPlaceholder.call(inputmask, position, test, true) || test.def) : elem; | ||
function _isValid(position, c, strict) { | ||
let rslt = false; | ||
getTests.call(inputmask, position).every(function (tst, ndx) { | ||
const test = tst.match; | ||
// make sure the buffer is set and correct | ||
getBuffer.call(inputmask, true); | ||
if ( | ||
test.jit && | ||
maskset.validPositions[seekPrevious.call(inputmask, position)] === | ||
undefined | ||
) { | ||
// ignore if jit is not desirable | ||
rslt = false; | ||
} else { | ||
// return is false or a json object => { pos: ??, c: ??} or true | ||
rslt = | ||
test.fn != null | ||
? test.fn.test( | ||
c, | ||
maskset, | ||
position, | ||
strict, | ||
opts, | ||
isSelection.call(inputmask, pos) | ||
) | ||
: (c === test.def || c === opts.skipOptionalPartCharacter) && | ||
test.def !== "" // non mask | ||
? { | ||
c: | ||
getPlaceholder.call(inputmask, position, test, true) || | ||
test.def, | ||
pos: position | ||
} | ||
: false; | ||
} | ||
if (rslt !== false) { | ||
let elem = rslt.c !== undefined ? rslt.c : c, | ||
validatedPos = position; | ||
elem = | ||
elem === opts.skipOptionalPartCharacter && test.static === true | ||
? getPlaceholder.call(inputmask, position, test, true) || test.def | ||
: elem; | ||
rslt = processCommandObject(rslt); | ||
rslt = processCommandObject(rslt); | ||
if (rslt !== true && rslt.pos !== undefined && rslt.pos !== position) { //their is a position offset | ||
validatedPos = rslt.pos; | ||
} | ||
if (rslt !== true && rslt.pos !== undefined && rslt.pos !== position) { | ||
// their is a position offset | ||
validatedPos = rslt.pos; | ||
} | ||
if (rslt !== true && rslt.pos === undefined && rslt.c === undefined) { | ||
return false; //breakout if nothing to insert | ||
} | ||
if (rslt !== true && rslt.pos === undefined && rslt.c === undefined) { | ||
return false; // breakout if nothing to insert | ||
} | ||
if (revalidateMask.call(inputmask, pos, $.extend({}, tst, { | ||
"input": casing.call(inputmask, elem, test, validatedPos) | ||
}), fromIsValid, validatedPos) === false) { | ||
rslt = false; | ||
} | ||
return false; //break from loop | ||
} | ||
if ( | ||
revalidateMask.call( | ||
inputmask, | ||
pos, | ||
$.extend({}, tst, { | ||
input: casing.call(inputmask, elem, test, validatedPos) | ||
}), | ||
fromIsValid, | ||
validatedPos | ||
) === false | ||
) { | ||
rslt = false; | ||
} | ||
return false; // break from loop | ||
} | ||
return true; | ||
}); | ||
return rslt; | ||
} | ||
return true; | ||
}); | ||
return rslt; | ||
} | ||
var result = true, | ||
positionsClone = $.extend(true, [], maskset.validPositions); //clone the currentPositions | ||
let result = true, | ||
positionsClone = $.extend(true, [], maskset.validPositions); // clone the currentPositions | ||
if (opts.keepStatic === false && maskset.excludes[maskPos] !== undefined && fromAlternate !== true && fromIsValid !== true) { | ||
for (var i = maskPos; i < (inputmask.isRTL ? pos.begin : pos.end); i++) { | ||
if (maskset.excludes[i] !== undefined) { | ||
maskset.excludes[i] = undefined; | ||
delete maskset.tests[i]; | ||
} | ||
} | ||
} | ||
if ( | ||
opts.keepStatic === false && | ||
maskset.excludes[maskPos] !== undefined && | ||
fromAlternate !== true && | ||
fromIsValid !== true | ||
) { | ||
for (let i = maskPos; i < (inputmask.isRTL ? pos.begin : pos.end); i++) { | ||
if (maskset.excludes[i] !== undefined) { | ||
maskset.excludes[i] = undefined; | ||
delete maskset.tests[i]; | ||
} | ||
} | ||
} | ||
if (typeof opts.preValidation === "function" && fromIsValid !== true && validateOnly !== true) { | ||
result = opts.preValidation.call(inputmask, getBuffer.call(inputmask), maskPos, c, isSelection.call(inputmask, pos), opts, maskset, pos, strict || fromAlternate); | ||
result = processCommandObject(result); | ||
} | ||
if (result === true) { //preValidation result | ||
result = _isValid(maskPos, c, strict); | ||
if ((!strict || fromIsValid === true) && result === false && validateOnly !== true) { | ||
var currentPosValid = maskset.validPositions[maskPos]; | ||
if (currentPosValid && currentPosValid.match.static === true && (currentPosValid.match.def === c || c === opts.skipOptionalPartCharacter)) { | ||
result = { | ||
"caret": seekNext.call(inputmask, maskPos) | ||
}; | ||
} else { | ||
if (opts.insertMode || maskset.validPositions[seekNext.call(inputmask, maskPos)] === undefined || pos.end > maskPos) { //does the input match on a further position? | ||
var skip = false; | ||
if (maskset.jitOffset[maskPos] && maskset.validPositions[seekNext.call(inputmask, maskPos)] === undefined) { | ||
result = isValid.call(inputmask, maskPos + maskset.jitOffset[maskPos], c, true, true); | ||
if (result !== false) { | ||
if (fromAlternate !== true) result.caret = maskPos; | ||
skip = true; | ||
} | ||
} | ||
if (pos.end > maskPos) { | ||
maskset.validPositions[maskPos] = undefined; | ||
} | ||
if (!skip && !isMask.call(inputmask, maskPos, opts.keepStatic && maskPos === 0)) { | ||
for (var nPos = maskPos + 1, snPos = seekNext.call(inputmask, maskPos, false, maskPos !== 0); nPos <= snPos; nPos++) { | ||
// if (!isMask(nPos, true)) { | ||
// continue; | ||
// } | ||
result = _isValid(nPos, c, strict); | ||
if (result !== false) { | ||
result = trackbackPositions.call(inputmask, maskPos, result.pos !== undefined ? result.pos : nPos) || result; | ||
maskPos = nPos; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
if ( | ||
typeof opts.preValidation === "function" && | ||
fromIsValid !== true && | ||
validateOnly !== true | ||
) { | ||
result = opts.preValidation.call( | ||
inputmask, | ||
getBuffer.call(inputmask), | ||
maskPos, | ||
c, | ||
isSelection.call(inputmask, pos), | ||
opts, | ||
maskset, | ||
pos, | ||
strict || fromAlternate | ||
); | ||
result = processCommandObject(result); | ||
} | ||
if (result === true) { | ||
// preValidation result | ||
result = _isValid(maskPos, c, strict); | ||
if ( | ||
(!strict || fromIsValid === true) && | ||
result === false && | ||
validateOnly !== true | ||
) { | ||
const currentPosValid = maskset.validPositions[maskPos]; | ||
if ( | ||
currentPosValid && | ||
currentPosValid.match.static === true && | ||
(currentPosValid.match.def === c || | ||
c === opts.skipOptionalPartCharacter) | ||
) { | ||
result = { | ||
caret: seekNext.call(inputmask, maskPos) | ||
}; | ||
} else { | ||
if ( | ||
opts.insertMode || | ||
maskset.validPositions[seekNext.call(inputmask, maskPos)] === | ||
undefined || | ||
pos.end > maskPos | ||
) { | ||
// does the input match on a further position? | ||
let skip = false; | ||
if ( | ||
maskset.jitOffset[maskPos] && | ||
maskset.validPositions[seekNext.call(inputmask, maskPos)] === | ||
undefined | ||
) { | ||
result = isValid.call( | ||
inputmask, | ||
maskPos + maskset.jitOffset[maskPos], | ||
c, | ||
true, | ||
true | ||
); | ||
if (result !== false) { | ||
if (fromAlternate !== true) result.caret = maskPos; | ||
skip = true; | ||
} | ||
} | ||
if (pos.end > maskPos) { | ||
maskset.validPositions[maskPos] = undefined; | ||
} | ||
if ( | ||
!skip && | ||
!isMask.call(inputmask, maskPos, opts.keepStatic && maskPos === 0) | ||
) { | ||
for ( | ||
let nPos = maskPos + 1, | ||
snPos = seekNext.call(inputmask, maskPos, false, maskPos !== 0); | ||
nPos <= snPos; | ||
nPos++ | ||
) { | ||
// if (!isMask(nPos, true)) { | ||
// continue; | ||
// } | ||
result = _isValid(nPos, c, strict); | ||
if (result !== false) { | ||
result = | ||
trackbackPositions.call( | ||
inputmask, | ||
maskPos, | ||
result.pos !== undefined ? result.pos : nPos | ||
) || result; | ||
maskPos = nPos; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
if (inputmask.hasAlternator && fromAlternate !== true && !strict) { | ||
fromAlternate = true; //stop possible loop | ||
if (result === false && opts.keepStatic && (isComplete.call(inputmask, getBuffer.call(inputmask)) || maskPos === 0)) { //try fuzzy alternator logic | ||
result = alternate.call(inputmask, maskPos, c, strict, fromIsValid, undefined, pos); | ||
} else if (isSelection.call(inputmask, pos) && maskset.tests[maskPos] && maskset.tests[maskPos].length > 1 && opts.keepStatic) { //selection clears an alternated keepstatic mask ~ #2189 | ||
result = alternate.call(inputmask, true); | ||
} else if (result == true && opts.numericInput !== true && maskset.tests[maskPos] && maskset.tests[maskPos].length > 1 && getLastValidPosition.call(inputmask, undefined, true) > maskPos) { | ||
// console.log("Alternating"); | ||
result = alternate.call(inputmask, true); | ||
} | ||
} | ||
if (inputmask.hasAlternator && fromAlternate !== true && !strict) { | ||
fromAlternate = true; // stop possible loop | ||
if ( | ||
result === false && | ||
opts.keepStatic && | ||
(isComplete.call(inputmask, getBuffer.call(inputmask)) || maskPos === 0) | ||
) { | ||
// try fuzzy alternator logic | ||
result = alternate.call( | ||
inputmask, | ||
maskPos, | ||
c, | ||
strict, | ||
fromIsValid, | ||
undefined, | ||
pos | ||
); | ||
} else if ( | ||
isSelection.call(inputmask, pos) && | ||
maskset.tests[maskPos] && | ||
maskset.tests[maskPos].length > 1 && | ||
opts.keepStatic | ||
) { | ||
// selection clears an alternated keepstatic mask ~ #2189 | ||
result = alternate.call(inputmask, true); | ||
} else if ( | ||
result == true && | ||
opts.numericInput !== true && | ||
maskset.tests[maskPos] && | ||
maskset.tests[maskPos].length > 1 && | ||
getLastValidPosition.call(inputmask, undefined, true) > maskPos | ||
) { | ||
// console.log("Alternating"); | ||
result = alternate.call(inputmask, true); | ||
} | ||
} | ||
if (result === true) { | ||
result = { | ||
"pos": maskPos | ||
}; | ||
} | ||
} | ||
if (typeof opts.postValidation === "function" && fromIsValid !== true && validateOnly !== true) { | ||
var postResult = opts.postValidation.call(inputmask, getBuffer.call(inputmask, true), pos.begin !== undefined ? (inputmask.isRTL ? pos.end : pos.begin) : pos, c, result, opts, maskset, strict, fromCheckval); | ||
if (postResult !== undefined) { | ||
result = postResult === true ? result : postResult; | ||
} | ||
} | ||
if (result === true) { | ||
result = { | ||
pos: maskPos | ||
}; | ||
} | ||
} | ||
if ( | ||
typeof opts.postValidation === "function" && | ||
fromIsValid !== true && | ||
validateOnly !== true | ||
) { | ||
const postResult = opts.postValidation.call( | ||
inputmask, | ||
getBuffer.call(inputmask, true), | ||
pos.begin !== undefined ? (inputmask.isRTL ? pos.end : pos.begin) : pos, | ||
c, | ||
result, | ||
opts, | ||
maskset, | ||
strict, | ||
fromCheckval | ||
); | ||
if (postResult !== undefined) { | ||
result = postResult === true ? result : postResult; | ||
} | ||
} | ||
if (result && result.pos === undefined) { | ||
result.pos = maskPos; | ||
} | ||
if (result && result.pos === undefined) { | ||
result.pos = maskPos; | ||
} | ||
if (result === false || validateOnly === true) { | ||
resetMaskSet.call(inputmask, true); | ||
maskset.validPositions = $.extend(true, [], positionsClone); //revert validation changes | ||
} else { | ||
trackbackPositions.call(inputmask, undefined, maskPos, true); | ||
} | ||
if (result === false || validateOnly === true) { | ||
resetMaskSet.call(inputmask, true); | ||
maskset.validPositions = $.extend(true, [], positionsClone); // revert validation changes | ||
} else { | ||
trackbackPositions.call(inputmask, undefined, maskPos, true); | ||
} | ||
var endResult = processCommandObject(result); | ||
// console.log("returned result " + JSON.stringify(endResult)); | ||
if (inputmask.maxLength !== undefined) { | ||
var buffer = getBuffer.call(inputmask); | ||
if (buffer.length > inputmask.maxLength && !fromIsValid) { | ||
resetMaskSet.call(inputmask, true); | ||
maskset.validPositions = $.extend(true, [], positionsClone); //revert validation changes | ||
endResult = false; | ||
} | ||
} | ||
return endResult; | ||
let endResult = processCommandObject(result); | ||
// console.log("returned result " + JSON.stringify(endResult)); | ||
if (inputmask.maxLength !== undefined) { | ||
const buffer = getBuffer.call(inputmask); | ||
if (buffer.length > inputmask.maxLength && !fromIsValid) { | ||
resetMaskSet.call(inputmask, true); | ||
maskset.validPositions = $.extend(true, [], positionsClone); // revert validation changes | ||
endResult = false; | ||
} | ||
} | ||
return endResult; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function positionCanMatchDefinition(pos, testDefinition, opts) { | ||
const inputmask = this, | ||
maskset = this.maskset; | ||
const inputmask = this, | ||
maskset = this.maskset; | ||
var valid = false, | ||
tests = getTests.call(inputmask, pos); | ||
for (var tndx = 0; tndx < tests.length; tndx++) { | ||
if (tests[tndx].match && | ||
((tests[tndx].match["nativeDef"] === testDefinition.match[opts.shiftPositions ? "def" : "nativeDef"] && (!opts.shiftPositions || !testDefinition.match.static)) || | ||
tests[tndx].match["nativeDef"] === testDefinition.match["nativeDef"] || | ||
(opts.regex && !tests[tndx].match.static && tests[tndx].match.fn.test(testDefinition.input, maskset, pos, false, opts)))) { | ||
valid = true; | ||
break; | ||
} else if (tests[tndx].match && tests[tndx].match["def"] === testDefinition.match["nativeDef"]) { | ||
valid = undefined; | ||
break; | ||
} | ||
} | ||
if (valid === false) { | ||
if (maskset.jitOffset[pos] !== undefined) { | ||
valid = positionCanMatchDefinition.call(inputmask, pos + maskset.jitOffset[pos], testDefinition, opts); | ||
} | ||
} | ||
return valid; | ||
let valid = false, | ||
tests = getTests.call(inputmask, pos); | ||
for (let tndx = 0; tndx < tests.length; tndx++) { | ||
if ( | ||
tests[tndx].match && | ||
((tests[tndx].match.nativeDef === | ||
testDefinition.match[opts.shiftPositions ? "def" : "nativeDef"] && | ||
(!opts.shiftPositions || !testDefinition.match.static)) || | ||
tests[tndx].match.nativeDef === testDefinition.match.nativeDef || | ||
(opts.regex && | ||
!tests[tndx].match.static && | ||
tests[tndx].match.fn.test( | ||
testDefinition.input, | ||
maskset, | ||
pos, | ||
false, | ||
opts | ||
))) | ||
) { | ||
valid = true; | ||
break; | ||
} else if ( | ||
tests[tndx].match && | ||
tests[tndx].match.def === testDefinition.match.nativeDef | ||
) { | ||
valid = undefined; | ||
break; | ||
} | ||
} | ||
if (valid === false) { | ||
if (maskset.jitOffset[pos] !== undefined) { | ||
valid = positionCanMatchDefinition.call( | ||
inputmask, | ||
pos + maskset.jitOffset[pos], | ||
testDefinition, | ||
opts | ||
); | ||
} | ||
} | ||
return valid; | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function refreshFromBuffer(start, end, buffer) { | ||
const inputmask = this, | ||
maskset = this.maskset, | ||
opts = this.opts, | ||
$ = this.dependencyLib; | ||
// checkVal.call(inputmask, el, false, true, isRTL ? buffer.reverse() : buffer); | ||
var i, p, skipOptionalPartCharacter = opts.skipOptionalPartCharacter, | ||
bffr = inputmask.isRTL ? buffer.slice().reverse() : buffer; | ||
opts.skipOptionalPartCharacter = ""; | ||
if (start === true) { | ||
resetMaskSet.call(inputmask, false); | ||
start = 0; | ||
end = buffer.length; | ||
p = determineNewCaretPosition.call(inputmask, {begin: 0, end: 0}, false).begin; | ||
} else { | ||
for (i = start; i < end; i++) { | ||
maskset.validPositions.splice(start, 0); | ||
} | ||
p = start; | ||
} | ||
const inputmask = this, | ||
maskset = this.maskset, | ||
opts = this.opts, | ||
$ = this.dependencyLib; | ||
// checkVal.call(inputmask, el, false, true, isRTL ? buffer.reverse() : buffer); | ||
let i, | ||
p, | ||
skipOptionalPartCharacter = opts.skipOptionalPartCharacter, | ||
bffr = inputmask.isRTL ? buffer.slice().reverse() : buffer; | ||
opts.skipOptionalPartCharacter = ""; | ||
if (start === true) { | ||
resetMaskSet.call(inputmask, false); | ||
start = 0; | ||
end = buffer.length; | ||
p = determineNewCaretPosition.call( | ||
inputmask, | ||
{ begin: 0, end: 0 }, | ||
false | ||
).begin; | ||
} else { | ||
for (i = start; i < end; i++) { | ||
maskset.validPositions.splice(start, 0); | ||
} | ||
p = start; | ||
} | ||
var keypress = new $.Event("keypress"); | ||
for (i = start; i < end; i++) { | ||
keypress.key = bffr[i].toString(); | ||
inputmask.ignorable = false; //make sure ignorable is ignored ;-) | ||
var valResult = EventHandlers.keypressEvent.call(inputmask, keypress, true, false, false, p); | ||
if (valResult !== false && valResult !== undefined) { | ||
p = valResult.forwardPosition; | ||
} | ||
} | ||
const keypress = new $.Event("keypress"); | ||
for (i = start; i < end; i++) { | ||
keypress.key = bffr[i].toString(); | ||
inputmask.ignorable = false; // make sure ignorable is ignored ;-) | ||
const valResult = EventHandlers.keypressEvent.call( | ||
inputmask, | ||
keypress, | ||
true, | ||
false, | ||
false, | ||
p | ||
); | ||
if (valResult !== false && valResult !== undefined) { | ||
p = valResult.forwardPosition; | ||
} | ||
} | ||
opts.skipOptionalPartCharacter = skipOptionalPartCharacter; | ||
opts.skipOptionalPartCharacter = skipOptionalPartCharacter; | ||
} | ||
//tobe put on prototype? | ||
//fill in best positions according the current input | ||
// tobe put on prototype? | ||
// fill in best positions according the current input | ||
function trackbackPositions(originalPos, newPos, fillOnly) { | ||
const inputmask = this, | ||
maskset = this.maskset, | ||
$ = this.dependencyLib; | ||
const inputmask = this, | ||
maskset = this.maskset, | ||
$ = this.dependencyLib; | ||
// console.log("trackbackPositions " + originalPos + " " + newPos); | ||
if (originalPos === undefined) { | ||
//find previous valid | ||
for (originalPos = newPos - 1; originalPos > 0; originalPos--) { | ||
if (maskset.validPositions[originalPos]) break; | ||
} | ||
} | ||
for (var ps = originalPos; ps < newPos; ps++) { | ||
if (maskset.validPositions[ps] === undefined && !isMask.call(inputmask, ps, false)) { | ||
var vp = ps == 0 ? getTest.call(inputmask, ps) : maskset.validPositions[ps - 1]; | ||
if (vp) { | ||
var tests = getTests.call(inputmask, ps).slice(); | ||
if (tests[tests.length - 1].match.def === "") tests.pop(); | ||
var bestMatch = determineTestTemplate.call(inputmask, ps, tests), np; | ||
if (bestMatch && (bestMatch.match.jit !== true || (bestMatch.match.newBlockMarker === "master" && (np = maskset.validPositions[ps + 1]) && np.match.optionalQuantifier === true))) { | ||
bestMatch = $.extend({}, bestMatch, { | ||
"input": getPlaceholder.call(inputmask, ps, bestMatch.match, true) || bestMatch.match.def | ||
}); | ||
bestMatch.generatedInput = true; | ||
revalidateMask.call(inputmask, ps, bestMatch, true); | ||
// console.log("trackbackPositions " + originalPos + " " + newPos); | ||
if (originalPos === undefined) { | ||
// find previous valid | ||
for (originalPos = newPos - 1; originalPos > 0; originalPos--) { | ||
if (maskset.validPositions[originalPos]) break; | ||
} | ||
} | ||
for (let ps = originalPos; ps < newPos; ps++) { | ||
if ( | ||
maskset.validPositions[ps] === undefined && | ||
!isMask.call(inputmask, ps, false) | ||
) { | ||
const vp = | ||
ps == 0 ? getTest.call(inputmask, ps) : maskset.validPositions[ps - 1]; | ||
if (vp) { | ||
const tests = getTests.call(inputmask, ps).slice(); | ||
if (tests[tests.length - 1].match.def === "") tests.pop(); | ||
var bestMatch = determineTestTemplate.call(inputmask, ps, tests), | ||
np; | ||
if ( | ||
bestMatch && | ||
(bestMatch.match.jit !== true || | ||
(bestMatch.match.newBlockMarker === "master" && | ||
(np = maskset.validPositions[ps + 1]) && | ||
np.match.optionalQuantifier === true)) | ||
) { | ||
bestMatch = $.extend({}, bestMatch, { | ||
input: | ||
getPlaceholder.call(inputmask, ps, bestMatch.match, true) || | ||
bestMatch.match.def | ||
}); | ||
bestMatch.generatedInput = true; | ||
revalidateMask.call(inputmask, ps, bestMatch, true); | ||
if (fillOnly !== true) { | ||
//revalidate the new position to update the locator value | ||
var cvpInput = maskset.validPositions[newPos].input; | ||
maskset.validPositions[newPos] = undefined; | ||
return isValid.call(inputmask, newPos, cvpInput, true, true); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
if (fillOnly !== true) { | ||
// revalidate the new position to update the locator value | ||
const cvpInput = maskset.validPositions[newPos].input; | ||
maskset.validPositions[newPos] = undefined; | ||
return isValid.call(inputmask, newPos, cvpInput, true, true); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
//tobe put on prototype? | ||
// tobe put on prototype? | ||
function revalidateMask(pos, validTest, fromIsValid, validatedPos) { | ||
const inputmask = this, | ||
maskset = this.maskset, | ||
opts = this.opts, | ||
$ = this.dependencyLib; | ||
// console.log("revalidateMask " + fromIsValid); | ||
const inputmask = this, | ||
maskset = this.maskset, | ||
opts = this.opts, | ||
$ = this.dependencyLib; | ||
function IsEnclosedStatic(pos, valids, selection) { | ||
var posMatch = valids[pos]; | ||
if (posMatch !== undefined && posMatch.match.static === true && posMatch.match.optionality !== true && (valids[0] === undefined || valids[0].alternation === undefined)) { | ||
var prevMatch = selection.begin <= pos - 1 ? valids[pos - 1] && valids[pos - 1].match.static === true && valids[pos - 1] : valids[pos - 1], | ||
nextMatch = selection.end > pos + 1 ? valids[pos + 1] && valids[pos + 1].match.static === true && valids[pos + 1] : valids[pos + 1]; | ||
return prevMatch && nextMatch; | ||
} | ||
return false; | ||
} | ||
function IsEnclosedStatic(pos, valids, selection) { | ||
const posMatch = valids[pos]; | ||
if ( | ||
posMatch !== undefined && | ||
posMatch.match.static === true && | ||
posMatch.match.optionality !== true && | ||
(valids[0] === undefined || valids[0].alternation === undefined) | ||
) { | ||
const prevMatch = | ||
selection.begin <= pos - 1 | ||
? valids[pos - 1] && | ||
valids[pos - 1].match.static === true && | ||
valids[pos - 1] | ||
: valids[pos - 1], | ||
nextMatch = | ||
selection.end > pos + 1 | ||
? valids[pos + 1] && | ||
valids[pos + 1].match.static === true && | ||
valids[pos + 1] | ||
: valids[pos + 1]; | ||
return prevMatch && nextMatch; | ||
} | ||
return false; | ||
} | ||
var offset = 0, begin = pos.begin !== undefined ? pos.begin : pos, end = pos.end !== undefined ? pos.end : pos, | ||
valid = true; | ||
if (pos.begin > pos.end) { | ||
begin = pos.end; | ||
end = pos.begin; | ||
} | ||
let offset = 0, | ||
begin = pos.begin !== undefined ? pos.begin : pos, | ||
end = pos.end !== undefined ? pos.end : pos, | ||
valid = true; | ||
if (pos.begin > pos.end) { | ||
begin = pos.end; | ||
end = pos.begin; | ||
} | ||
validatedPos = validatedPos !== undefined ? validatedPos : begin; | ||
if (fromIsValid === undefined && (begin !== end || (opts.insertMode && maskset.validPositions[validatedPos] !== undefined) || validTest === undefined || validTest.match.optionalQuantifier || validTest.match.optionality)) { | ||
//reposition & revalidate others | ||
var positionsClone = $.extend(true, [], maskset.validPositions), | ||
lvp = getLastValidPosition.call(inputmask, undefined, true), | ||
i; | ||
maskset.p = begin; //needed for alternated position after overtype selection | ||
validatedPos = validatedPos !== undefined ? validatedPos : begin; | ||
if ( | ||
fromIsValid === undefined && | ||
(begin !== end || | ||
(opts.insertMode && maskset.validPositions[validatedPos] !== undefined) || | ||
validTest === undefined || | ||
validTest.match.optionalQuantifier || | ||
validTest.match.optionality) | ||
) { | ||
// reposition & revalidate others | ||
let positionsClone = $.extend(true, [], maskset.validPositions), | ||
lvp = getLastValidPosition.call(inputmask, undefined, true), | ||
i; | ||
maskset.p = begin; // needed for alternated position after overtype selection | ||
var clearpos = isSelection.call(inputmask, pos) ? begin : validatedPos; | ||
for (i = lvp; i >= clearpos; i--) { | ||
maskset.validPositions.splice(i, 1); | ||
if (validTest === undefined) delete maskset.tests[i + 1]; | ||
} | ||
const clearpos = isSelection.call(inputmask, pos) ? begin : validatedPos; | ||
for (i = lvp; i >= clearpos; i--) { | ||
maskset.validPositions.splice(i, 1); | ||
if (validTest === undefined) delete maskset.tests[i + 1]; | ||
} | ||
var j = validatedPos, | ||
posMatch = j, t, canMatch, test; | ||
let j = validatedPos, | ||
posMatch = j, | ||
t, | ||
canMatch, | ||
test; | ||
if (validTest) { | ||
maskset.validPositions[validatedPos] = $.extend(true, {}, validTest); | ||
posMatch++; | ||
j++; | ||
} | ||
if (validTest) { | ||
maskset.validPositions[validatedPos] = $.extend(true, {}, validTest); | ||
posMatch++; | ||
j++; | ||
} | ||
if (positionsClone[end] == undefined && maskset.jitOffset[end]) { | ||
end += maskset.jitOffset[end] + 1; | ||
} | ||
for (i = (validTest ? end : end - 1); i <= lvp; i++) { | ||
if ((t = positionsClone[i]) !== undefined && t.generatedInput !== true && | ||
(i >= end || (i >= begin && IsEnclosedStatic(i, positionsClone, { | ||
begin: begin, | ||
end: end | ||
})))) { | ||
while (test = getTest.call(inputmask, posMatch), test.match.def !== "") { //loop needed to match further positions | ||
if ((canMatch = positionCanMatchDefinition.call(inputmask, posMatch, t, opts)) !== false || t.match.def === "+") { //validated match //we still need some hackery for the + validator (numeric alias) | ||
if (t.match.def === "+") getBuffer.call(inputmask, true); | ||
var result = isValid.call(inputmask, posMatch, t.input, t.match.def !== "+", /*t.match.def !== "+"*/ true); | ||
valid = result !== false; | ||
j = (result.pos || posMatch) + 1; | ||
if (!valid && canMatch) break; | ||
} else { | ||
valid = false; | ||
} | ||
if (valid) { | ||
if (validTest === undefined && t.match.static && i === pos.begin) offset++; | ||
break; | ||
} | ||
if (!valid && getBuffer.call(inputmask), posMatch > maskset.maskLength) { | ||
break; | ||
} | ||
posMatch++; | ||
} | ||
if (getTest.call(inputmask, posMatch).match.def == "") { | ||
valid = false; | ||
} | ||
//restore position | ||
posMatch = j; | ||
} | ||
if (!valid) break; | ||
} | ||
if (!valid) { | ||
maskset.validPositions = $.extend(true, [], positionsClone); | ||
resetMaskSet.call(inputmask, true); | ||
return false; | ||
} | ||
} else if (validTest && getTest.call(inputmask, validatedPos).match.cd === validTest.match.cd) { | ||
maskset.validPositions[validatedPos] = $.extend(true, {}, validTest); | ||
} | ||
if (positionsClone[end] == undefined && maskset.jitOffset[end]) { | ||
end += maskset.jitOffset[end] + 1; | ||
} | ||
for (i = validTest ? end : end - 1; i <= lvp; i++) { | ||
if ( | ||
(t = positionsClone[i]) !== undefined && | ||
t.generatedInput !== true && | ||
(i >= end || | ||
(i >= begin && | ||
IsEnclosedStatic(i, positionsClone, { | ||
begin, | ||
end | ||
}))) | ||
) { | ||
while ( | ||
((test = getTest.call(inputmask, posMatch)), test.match.def !== "") | ||
) { | ||
// loop needed to match further positions | ||
if ( | ||
(canMatch = positionCanMatchDefinition.call( | ||
inputmask, | ||
posMatch, | ||
t, | ||
opts | ||
)) !== false || | ||
t.match.def === "+" | ||
) { | ||
// validated match //we still need some hackery for the + validator (numeric alias) | ||
if (t.match.def === "+") getBuffer.call(inputmask, true); | ||
const result = isValid.call( | ||
inputmask, | ||
posMatch, | ||
t.input, | ||
t.match.def !== "+", | ||
/* t.match.def !== "+" */ true | ||
); | ||
valid = result !== false; | ||
j = (result.pos || posMatch) + 1; | ||
if (!valid && canMatch) break; | ||
} else { | ||
valid = false; | ||
} | ||
if (valid) { | ||
if (validTest === undefined && t.match.static && i === pos.begin) | ||
offset++; | ||
break; | ||
} | ||
if ( | ||
(!valid && getBuffer.call(inputmask), posMatch > maskset.maskLength) | ||
) { | ||
break; | ||
} | ||
posMatch++; | ||
} | ||
if (getTest.call(inputmask, posMatch).match.def == "") { | ||
valid = false; | ||
} | ||
// restore position | ||
posMatch = j; | ||
} | ||
if (!valid) break; | ||
} | ||
if (!valid) { | ||
maskset.validPositions = $.extend(true, [], positionsClone); | ||
resetMaskSet.call(inputmask, true); | ||
return false; | ||
} | ||
} else if ( | ||
validTest && | ||
getTest.call(inputmask, validatedPos).match.cd === validTest.match.cd | ||
) { | ||
maskset.validPositions[validatedPos] = $.extend(true, {}, validTest); | ||
} | ||
resetMaskSet.call(inputmask, true); | ||
return offset; | ||
resetMaskSet.call(inputmask, true); | ||
return offset; | ||
} |
(() => { | ||
window.mm = (i, mask) => { | ||
const d = {9: "[0-9]", a: "[a-z]"}, msk = mask.split(""); | ||
i.addEventListener("input", handler); | ||
i.addEventListener("focus", handler); | ||
window.mm = (i, mask) => { | ||
const d = { 9: "[0-9]", a: "[a-z]" }, | ||
msk = mask.split(""); | ||
i.addEventListener("input", handler); | ||
i.addEventListener("focus", handler); | ||
function handler(e) { | ||
if (e.type === "focus" && i.value !== "") return; | ||
let mskd = [], | ||
s = i.selectionStart - 1; | ||
msk.forEach((el, n) => { | ||
if (d[el]) { | ||
let t = new RegExp(d[el], "i").test(i.value.charAt(n)); | ||
mskd.push(t ? i.value.charAt(n) : "_"); | ||
if (t && s === n && i.value.charAt(n) !== "_") { | ||
s++; | ||
} | ||
} else { | ||
mskd.push(el); | ||
if (s === n) s++; | ||
} | ||
}); | ||
i.value = mskd.join(""); | ||
i.selectionStart = i.selectionEnd = s < 0 ? 0 : s; | ||
setTimeout(function () { | ||
i.selectionStart = i.selectionEnd = s < 0 ? 0 : s; | ||
}, 0); | ||
} | ||
}; | ||
})(); | ||
function handler(e) { | ||
if (e.type == "focus" && i.value !== "") return; | ||
const mskd = []; | ||
let s = i.selectionStart - 1; | ||
msk.forEach((el, n) => { | ||
if (d[el]) { | ||
const t = new RegExp(d[el], "i").test(i.value.charAt(n)); | ||
mskd.push(t ? i.value.charAt(n) : "_"); | ||
if (t && s === n && i.value.charAt(n) !== "_") { | ||
s++; | ||
} | ||
} else { | ||
mskd.push(el); | ||
if (s === n) s++; | ||
} | ||
}); | ||
i.value = mskd.join(""); | ||
i.selectionStart = i.selectionEnd = s < 0 ? 0 : s; | ||
setTimeout(function () { | ||
i.selectionStart = i.selectionEnd = s < 0 ? 0 : s; | ||
}, 0); | ||
} | ||
}; | ||
})(); |
{ | ||
"name": "inputmask", | ||
"version": "5.0.9-beta.62", | ||
"version": "5.0.9-beta.70", | ||
"description": "Inputmask is a javascript library which creates an input mask. Inputmask can run against vanilla javascript, jQuery and jqlite.", | ||
@@ -49,2 +49,3 @@ "main": "dist/inputmask.js", | ||
"@babel/core": "^7.23.2", | ||
"@babel/eslint-parser": "^7.24.1", | ||
"@babel/plugin-transform-modules-commonjs": "^7.23.0", | ||
@@ -73,4 +74,13 @@ "@babel/preset-env": "^7.23.2", | ||
"webpack": "^5.89.0", | ||
"webpack-cli": "^5.1.4" | ||
"webpack-cli": "^5.1.4", | ||
"prettier": "3.0.0", | ||
"eslint": "^8.46.0", | ||
"eslint-config-prettier": "^8.9.0", | ||
"eslint-config-standard": "^17.1.0", | ||
"eslint-plugin-header": "^3.1.1", | ||
"eslint-plugin-import": "^2.28.0", | ||
"eslint-plugin-n": "^16.0.1", | ||
"eslint-plugin-prettier": "^5.0.0", | ||
"eslint-plugin-promise": "^6.1.1" | ||
} | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
1403441
19462
35