| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- /*
- * Input Mask Core
- * http://github.com/RobinHerbots/jquery.inputmask
- * Copyright (c) Robin Herbots
- * Licensed under the MIT license
- */
- import defaults from "./defaults";
- import definitions from "./definitions";
- import $ from "./dependencyLibs/inputmask.dependencyLib";
- import { EventRuler } from "./eventruler";
- import window from "./global/window";
- 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";
- function 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;
- 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;
- // 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,
- 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) {
- 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
- 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) {
- 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);
- 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) {
- 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;
- }
- 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;
- }
- }
- if (opts.importDataAttributes === true) {
- let attrOptions = npt.getAttribute(dataAttribute),
- option,
- dataoptions,
- optionData,
- p;
- 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);
- }
- 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";
- }
- if (npt.dir === "rtl" || opts.numericInput) {
- npt.dir = "ltr";
- npt.removeAttribute("dir");
- opts.isRTL = true;
- }
- return Object.keys(userOptions).length;
- }
- // apply defaults, definitions, aliases
- Inputmask.extendDefaults = function (options) {
- $.extend(true, Inputmask.prototype.defaults, options);
- };
- Inputmask.extendDefinitions = function (definition) {
- $.extend(true, Inputmask.prototype.definitions, definition);
- };
- Inputmask.extendAliases = function (alias) {
- $.extend(true, Inputmask.prototype.aliases, alias);
- };
- // static fn on inputmask
- Inputmask.format = function (value, options, metadata) {
- return Inputmask(options).format(value, metadata);
- };
- Inputmask.unmask = function (value, options) {
- return Inputmask(options).unmaskedvalue(value);
- };
- Inputmask.isValid = function (value, options) {
- 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();
- });
- };
- 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]);
- });
- };
- Inputmask.dependencyLib = $;
- // make inputmask available
- window.Inputmask = Inputmask;
- export default Inputmask;
|