var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; var NumeralFormatter = function (numeralDecimalMark, numeralIntegerScale, numeralDecimalScale, numeralThousandsGroupStyle, numeralPositiveOnly, stripLeadingZeroes, prefix, signBeforePrefix, tailPrefix, delimiter) { var owner = this; owner.numeralDecimalMark = numeralDecimalMark || '.'; owner.numeralIntegerScale = numeralIntegerScale > 0 ? numeralIntegerScale : 0; owner.numeralDecimalScale = numeralDecimalScale >= 0 ? numeralDecimalScale : 2; owner.numeralThousandsGroupStyle = numeralThousandsGroupStyle || NumeralFormatter.groupStyle.thousand; owner.numeralPositiveOnly = !!numeralPositiveOnly; owner.stripLeadingZeroes = stripLeadingZeroes !== false; owner.prefix = (prefix || prefix === '') ? prefix : ''; owner.signBeforePrefix = !!signBeforePrefix; owner.tailPrefix = !!tailPrefix; owner.delimiter = (delimiter || delimiter === '') ? delimiter : ','; owner.delimiterRE = delimiter ? new RegExp('\\' + delimiter, 'g') : ''; }; NumeralFormatter.groupStyle = { thousand: 'thousand', lakh: 'lakh', wan: 'wan', none: 'none' }; NumeralFormatter.prototype = { getRawValue: function (value) { return value.replace(this.delimiterRE, '').replace(this.numeralDecimalMark, '.'); }, format: function (value) { var owner = this, parts, partSign, partSignAndPrefix, partInteger, partDecimal = ''; // strip alphabet letters value = value.replace(/[A-Za-z]/g, '') // replace the first decimal mark with reserved placeholder .replace(owner.numeralDecimalMark, 'M') // strip non numeric letters except minus and "M" // this is to ensure prefix has been stripped .replace(/[^\dM-]/g, '') // replace the leading minus with reserved placeholder .replace(/^\-/, 'N') // strip the other minus sign (if present) .replace(/\-/g, '') // replace the minus sign (if present) .replace('N', owner.numeralPositiveOnly ? '' : '-') // replace decimal mark .replace('M', owner.numeralDecimalMark); // strip any leading zeros if (owner.stripLeadingZeroes) { value = value.replace(/^(-)?0+(?=\d)/, '$1'); } partSign = value.slice(0, 1) === '-' ? '-' : ''; if (typeof owner.prefix != 'undefined') { if (owner.signBeforePrefix) { partSignAndPrefix = partSign + owner.prefix; } else { partSignAndPrefix = owner.prefix + partSign; } } else { partSignAndPrefix = partSign; } partInteger = value; if (value.indexOf(owner.numeralDecimalMark) >= 0) { parts = value.split(owner.numeralDecimalMark); partInteger = parts[0]; partDecimal = owner.numeralDecimalMark + parts[1].slice(0, owner.numeralDecimalScale); } if(partSign === '-') { partInteger = partInteger.slice(1); } if (owner.numeralIntegerScale > 0) { partInteger = partInteger.slice(0, owner.numeralIntegerScale); } switch (owner.numeralThousandsGroupStyle) { case NumeralFormatter.groupStyle.lakh: partInteger = partInteger.replace(/(\d)(?=(\d\d)+\d$)/g, '$1' + owner.delimiter); break; case NumeralFormatter.groupStyle.wan: partInteger = partInteger.replace(/(\d)(?=(\d{4})+$)/g, '$1' + owner.delimiter); break; case NumeralFormatter.groupStyle.thousand: partInteger = partInteger.replace(/(\d)(?=(\d{3})+$)/g, '$1' + owner.delimiter); break; } if (owner.tailPrefix) { return partSign + partInteger.toString() + (owner.numeralDecimalScale > 0 ? partDecimal.toString() : '') + owner.prefix; } return partSignAndPrefix + partInteger.toString() + (owner.numeralDecimalScale > 0 ? partDecimal.toString() : ''); } }; var NumeralFormatter_1 = NumeralFormatter; var DateFormatter = function (datePattern, dateMin, dateMax) { var owner = this; owner.date = []; owner.blocks = []; owner.datePattern = datePattern; owner.dateMin = dateMin .split('-') .reverse() .map(function(x) { return parseInt(x, 10); }); if (owner.dateMin.length === 2) owner.dateMin.unshift(0); owner.dateMax = dateMax .split('-') .reverse() .map(function(x) { return parseInt(x, 10); }); if (owner.dateMax.length === 2) owner.dateMax.unshift(0); owner.initBlocks(); }; DateFormatter.prototype = { initBlocks: function () { var owner = this; owner.datePattern.forEach(function (value) { if (value === 'Y') { owner.blocks.push(4); } else { owner.blocks.push(2); } }); }, getISOFormatDate: function () { var owner = this, date = owner.date; return date[2] ? ( date[2] + '-' + owner.addLeadingZero(date[1]) + '-' + owner.addLeadingZero(date[0]) ) : ''; }, getBlocks: function () { return this.blocks; }, getValidatedDate: function (value) { var owner = this, result = ''; value = value.replace(/[^\d]/g, ''); owner.blocks.forEach(function (length, index) { if (value.length > 0) { var sub = value.slice(0, length), sub0 = sub.slice(0, 1), rest = value.slice(length); switch (owner.datePattern[index]) { case 'd': if (sub === '00') { sub = '01'; } else if (parseInt(sub0, 10) > 3) { sub = '0' + sub0; } else if (parseInt(sub, 10) > 31) { sub = '31'; } break; case 'm': if (sub === '00') { sub = '01'; } else if (parseInt(sub0, 10) > 1) { sub = '0' + sub0; } else if (parseInt(sub, 10) > 12) { sub = '12'; } break; } result += sub; // update remaining string value = rest; } }); return this.getFixedDateString(result); }, getFixedDateString: function (value) { var owner = this, datePattern = owner.datePattern, date = [], dayIndex = 0, monthIndex = 0, yearIndex = 0, dayStartIndex = 0, monthStartIndex = 0, yearStartIndex = 0, day, month, year, fullYearDone = false; // mm-dd || dd-mm if (value.length === 4 && datePattern[0].toLowerCase() !== 'y' && datePattern[1].toLowerCase() !== 'y') { dayStartIndex = datePattern[0] === 'd' ? 0 : 2; monthStartIndex = 2 - dayStartIndex; day = parseInt(value.slice(dayStartIndex, dayStartIndex + 2), 10); month = parseInt(value.slice(monthStartIndex, monthStartIndex + 2), 10); date = this.getFixedDate(day, month, 0); } // yyyy-mm-dd || yyyy-dd-mm || mm-dd-yyyy || dd-mm-yyyy || dd-yyyy-mm || mm-yyyy-dd if (value.length === 8) { datePattern.forEach(function (type, index) { switch (type) { case 'd': dayIndex = index; break; case 'm': monthIndex = index; break; default: yearIndex = index; break; } }); yearStartIndex = yearIndex * 2; dayStartIndex = (dayIndex <= yearIndex) ? dayIndex * 2 : (dayIndex * 2 + 2); monthStartIndex = (monthIndex <= yearIndex) ? monthIndex * 2 : (monthIndex * 2 + 2); day = parseInt(value.slice(dayStartIndex, dayStartIndex + 2), 10); month = parseInt(value.slice(monthStartIndex, monthStartIndex + 2), 10); year = parseInt(value.slice(yearStartIndex, yearStartIndex + 4), 10); fullYearDone = value.slice(yearStartIndex, yearStartIndex + 4).length === 4; date = this.getFixedDate(day, month, year); } // mm-yy || yy-mm if (value.length === 4 && (datePattern[0] === 'y' || datePattern[1] === 'y')) { monthStartIndex = datePattern[0] === 'm' ? 0 : 2; yearStartIndex = 2 - monthStartIndex; month = parseInt(value.slice(monthStartIndex, monthStartIndex + 2), 10); year = parseInt(value.slice(yearStartIndex, yearStartIndex + 2), 10); fullYearDone = value.slice(yearStartIndex, yearStartIndex + 2).length === 2; date = [0, month, year]; } // mm-yyyy || yyyy-mm if (value.length === 6 && (datePattern[0] === 'Y' || datePattern[1] === 'Y')) { monthStartIndex = datePattern[0] === 'm' ? 0 : 4; yearStartIndex = 2 - 0.5 * monthStartIndex; month = parseInt(value.slice(monthStartIndex, monthStartIndex + 2), 10); year = parseInt(value.slice(yearStartIndex, yearStartIndex + 4), 10); fullYearDone = value.slice(yearStartIndex, yearStartIndex + 4).length === 4; date = [0, month, year]; } date = owner.getRangeFixedDate(date); owner.date = date; var result = date.length === 0 ? value : datePattern.reduce(function (previous, current) { switch (current) { case 'd': return previous + (date[0] === 0 ? '' : owner.addLeadingZero(date[0])); case 'm': return previous + (date[1] === 0 ? '' : owner.addLeadingZero(date[1])); case 'y': return previous + (fullYearDone ? owner.addLeadingZeroForYear(date[2], false) : ''); case 'Y': return previous + (fullYearDone ? owner.addLeadingZeroForYear(date[2], true) : ''); } }, ''); return result; }, getRangeFixedDate: function (date) { var owner = this, datePattern = owner.datePattern, dateMin = owner.dateMin || [], dateMax = owner.dateMax || []; if (!date.length || (dateMin.length < 3 && dateMax.length < 3)) return date; if ( datePattern.find(function(x) { return x.toLowerCase() === 'y'; }) && date[2] === 0 ) return date; if (dateMax.length && (dateMax[2] < date[2] || ( dateMax[2] === date[2] && (dateMax[1] < date[1] || ( dateMax[1] === date[1] && dateMax[0] < date[0] )) ))) return dateMax; if (dateMin.length && (dateMin[2] > date[2] || ( dateMin[2] === date[2] && (dateMin[1] > date[1] || ( dateMin[1] === date[1] && dateMin[0] > date[0] )) ))) return dateMin; return date; }, getFixedDate: function (day, month, year) { day = Math.min(day, 31); month = Math.min(month, 12); year = parseInt((year || 0), 10); if ((month < 7 && month % 2 === 0) || (month > 8 && month % 2 === 1)) { day = Math.min(day, month === 2 ? (this.isLeapYear(year) ? 29 : 28) : 30); } return [day, month, year]; }, isLeapYear: function (year) { return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0); }, addLeadingZero: function (number) { return (number < 10 ? '0' : '') + number; }, addLeadingZeroForYear: function (number, fullYearMode) { if (fullYearMode) { return (number < 10 ? '000' : (number < 100 ? '00' : (number < 1000 ? '0' : ''))) + number; } return (number < 10 ? '0' : '') + number; } }; var DateFormatter_1 = DateFormatter; var TimeFormatter = function (timePattern, timeFormat) { var owner = this; owner.time = []; owner.blocks = []; owner.timePattern = timePattern; owner.timeFormat = timeFormat; owner.initBlocks(); }; TimeFormatter.prototype = { initBlocks: function () { var owner = this; owner.timePattern.forEach(function () { owner.blocks.push(2); }); }, getISOFormatTime: function () { var owner = this, time = owner.time; return time[2] ? ( owner.addLeadingZero(time[0]) + ':' + owner.addLeadingZero(time[1]) + ':' + owner.addLeadingZero(time[2]) ) : ''; }, getBlocks: function () { return this.blocks; }, getTimeFormatOptions: function () { var owner = this; if (String(owner.timeFormat) === '12') { return { maxHourFirstDigit: 1, maxHours: 12, maxMinutesFirstDigit: 5, maxMinutes: 60 }; } return { maxHourFirstDigit: 2, maxHours: 23, maxMinutesFirstDigit: 5, maxMinutes: 60 }; }, getValidatedTime: function (value) { var owner = this, result = ''; value = value.replace(/[^\d]/g, ''); var timeFormatOptions = owner.getTimeFormatOptions(); owner.blocks.forEach(function (length, index) { if (value.length > 0) { var sub = value.slice(0, length), sub0 = sub.slice(0, 1), rest = value.slice(length); switch (owner.timePattern[index]) { case 'h': if (parseInt(sub0, 10) > timeFormatOptions.maxHourFirstDigit) { sub = '0' + sub0; } else if (parseInt(sub, 10) > timeFormatOptions.maxHours) { sub = timeFormatOptions.maxHours + ''; } break; case 'm': case 's': if (parseInt(sub0, 10) > timeFormatOptions.maxMinutesFirstDigit) { sub = '0' + sub0; } else if (parseInt(sub, 10) > timeFormatOptions.maxMinutes) { sub = timeFormatOptions.maxMinutes + ''; } break; } result += sub; // update remaining string value = rest; } }); return this.getFixedTimeString(result); }, getFixedTimeString: function (value) { var owner = this, timePattern = owner.timePattern, time = [], secondIndex = 0, minuteIndex = 0, hourIndex = 0, secondStartIndex = 0, minuteStartIndex = 0, hourStartIndex = 0, second, minute, hour; if (value.length === 6) { timePattern.forEach(function (type, index) { switch (type) { case 's': secondIndex = index * 2; break; case 'm': minuteIndex = index * 2; break; case 'h': hourIndex = index * 2; break; } }); hourStartIndex = hourIndex; minuteStartIndex = minuteIndex; secondStartIndex = secondIndex; second = parseInt(value.slice(secondStartIndex, secondStartIndex + 2), 10); minute = parseInt(value.slice(minuteStartIndex, minuteStartIndex + 2), 10); hour = parseInt(value.slice(hourStartIndex, hourStartIndex + 2), 10); time = this.getFixedTime(hour, minute, second); } if (value.length === 4 && owner.timePattern.indexOf('s') < 0) { timePattern.forEach(function (type, index) { switch (type) { case 'm': minuteIndex = index * 2; break; case 'h': hourIndex = index * 2; break; } }); hourStartIndex = hourIndex; minuteStartIndex = minuteIndex; second = 0; minute = parseInt(value.slice(minuteStartIndex, minuteStartIndex + 2), 10); hour = parseInt(value.slice(hourStartIndex, hourStartIndex + 2), 10); time = this.getFixedTime(hour, minute, second); } owner.time = time; return time.length === 0 ? value : timePattern.reduce(function (previous, current) { switch (current) { case 's': return previous + owner.addLeadingZero(time[2]); case 'm': return previous + owner.addLeadingZero(time[1]); case 'h': return previous + owner.addLeadingZero(time[0]); } }, ''); }, getFixedTime: function (hour, minute, second) { second = Math.min(parseInt(second || 0, 10), 60); minute = Math.min(minute, 60); hour = Math.min(hour, 60); return [hour, minute, second]; }, addLeadingZero: function (number) { return (number < 10 ? '0' : '') + number; } }; var TimeFormatter_1 = TimeFormatter; var PhoneFormatter = function (formatter, delimiter) { var owner = this; owner.delimiter = (delimiter || delimiter === '') ? delimiter : ' '; owner.delimiterRE = delimiter ? new RegExp('\\' + delimiter, 'g') : ''; owner.formatter = formatter; }; PhoneFormatter.prototype = { setFormatter: function (formatter) { this.formatter = formatter; }, format: function (phoneNumber) { var owner = this; owner.formatter.clear(); // only keep number and + phoneNumber = phoneNumber.replace(/[^\d+]/g, ''); // strip non-leading + phoneNumber = phoneNumber.replace(/^\+/, 'B').replace(/\+/g, '').replace('B', '+'); // strip delimiter phoneNumber = phoneNumber.replace(owner.delimiterRE, ''); var result = '', current, validated = false; for (var i = 0, iMax = phoneNumber.length; i < iMax; i++) { current = owner.formatter.inputDigit(phoneNumber.charAt(i)); // has ()- or space inside if (/[\s()-]/g.test(current)) { result = current; validated = true; } else { if (!validated) { result = current; } // else: over length input // it turns to invalid number again } } // strip () // e.g. US: 7161234567 returns (716) 123-4567 result = result.replace(/[()]/g, ''); // replace library delimiter with user customized delimiter result = result.replace(/[\s-]/g, owner.delimiter); return result; } }; var PhoneFormatter_1 = PhoneFormatter; var CreditCardDetector = { blocks: { uatp: [4, 5, 6], amex: [4, 6, 5], diners: [4, 6, 4], discover: [4, 4, 4, 4], mastercard: [4, 4, 4, 4], dankort: [4, 4, 4, 4], instapayment: [4, 4, 4, 4], jcb15: [4, 6, 5], jcb: [4, 4, 4, 4], maestro: [4, 4, 4, 4], visa: [4, 4, 4, 4], mir: [4, 4, 4, 4], unionPay: [4, 4, 4, 4], general: [4, 4, 4, 4] }, re: { // starts with 1; 15 digits, not starts with 1800 (jcb card) uatp: /^(?!1800)1\d{0,14}/, // starts with 34/37; 15 digits amex: /^3[47]\d{0,13}/, // starts with 6011/65/644-649; 16 digits discover: /^(?:6011|65\d{0,2}|64[4-9]\d?)\d{0,12}/, // starts with 300-305/309 or 36/38/39; 14 digits diners: /^3(?:0([0-5]|9)|[689]\d?)\d{0,11}/, // starts with 51-55/2221–2720; 16 digits mastercard: /^(5[1-5]\d{0,2}|22[2-9]\d{0,1}|2[3-7]\d{0,2})\d{0,12}/, // starts with 5019/4175/4571; 16 digits dankort: /^(5019|4175|4571)\d{0,12}/, // starts with 637-639; 16 digits instapayment: /^63[7-9]\d{0,13}/, // starts with 2131/1800; 15 digits jcb15: /^(?:2131|1800)\d{0,11}/, // starts with 2131/1800/35; 16 digits jcb: /^(?:35\d{0,2})\d{0,12}/, // starts with 50/56-58/6304/67; 16 digits maestro: /^(?:5[0678]\d{0,2}|6304|67\d{0,2})\d{0,12}/, // starts with 22; 16 digits mir: /^220[0-4]\d{0,12}/, // starts with 4; 16 digits visa: /^4\d{0,15}/, // starts with 62/81; 16 digits unionPay: /^(62|81)\d{0,14}/ }, getStrictBlocks: function (block) { var total = block.reduce(function (prev, current) { return prev + current; }, 0); return block.concat(19 - total); }, getInfo: function (value, strictMode) { var blocks = CreditCardDetector.blocks, re = CreditCardDetector.re; // Some credit card can have up to 19 digits number. // Set strictMode to true will remove the 16 max-length restrain, // however, I never found any website validate card number like // this, hence probably you don't want to enable this option. strictMode = !!strictMode; for (var key in re) { if (re[key].test(value)) { var matchedBlocks = blocks[key]; return { type: key, blocks: strictMode ? this.getStrictBlocks(matchedBlocks) : matchedBlocks }; } } return { type: 'unknown', blocks: strictMode ? this.getStrictBlocks(blocks.general) : blocks.general }; } }; var CreditCardDetector_1 = CreditCardDetector; var Util = { noop: function () { }, strip: function (value, re) { return value.replace(re, ''); }, getPostDelimiter: function (value, delimiter, delimiters) { // single delimiter if (delimiters.length === 0) { return value.slice(-delimiter.length) === delimiter ? delimiter : ''; } // multiple delimiters var matchedDelimiter = ''; delimiters.forEach(function (current) { if (value.slice(-current.length) === current) { matchedDelimiter = current; } }); return matchedDelimiter; }, getDelimiterREByDelimiter: function (delimiter) { return new RegExp(delimiter.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1'), 'g'); }, getNextCursorPosition: function (prevPos, oldValue, newValue, delimiter, delimiters) { // If cursor was at the end of value, just place it back. // Because new value could contain additional chars. if (oldValue.length === prevPos) { return newValue.length; } return prevPos + this.getPositionOffset(prevPos, oldValue, newValue, delimiter ,delimiters); }, getPositionOffset: function (prevPos, oldValue, newValue, delimiter, delimiters) { var oldRawValue, newRawValue, lengthOffset; oldRawValue = this.stripDelimiters(oldValue.slice(0, prevPos), delimiter, delimiters); newRawValue = this.stripDelimiters(newValue.slice(0, prevPos), delimiter, delimiters); lengthOffset = oldRawValue.length - newRawValue.length; return (lengthOffset !== 0) ? (lengthOffset / Math.abs(lengthOffset)) : 0; }, stripDelimiters: function (value, delimiter, delimiters) { var owner = this; // single delimiter if (delimiters.length === 0) { var delimiterRE = delimiter ? owner.getDelimiterREByDelimiter(delimiter) : ''; return value.replace(delimiterRE, ''); } // multiple delimiters delimiters.forEach(function (current) { current.split('').forEach(function (letter) { value = value.replace(owner.getDelimiterREByDelimiter(letter), ''); }); }); return value; }, headStr: function (str, length) { return str.slice(0, length); }, getMaxLength: function (blocks) { return blocks.reduce(function (previous, current) { return previous + current; }, 0); }, // strip prefix // Before type | After type | Return value // PEFIX-... | PEFIX-... | '' // PREFIX-123 | PEFIX-123 | 123 // PREFIX-123 | PREFIX-23 | 23 // PREFIX-123 | PREFIX-1234 | 1234 getPrefixStrippedValue: function (value, prefix, prefixLength, prevResult, delimiter, delimiters, noImmediatePrefix, tailPrefix, signBeforePrefix) { // No prefix if (prefixLength === 0) { return value; } // Value is prefix if (value === prefix && value !== '') { return ''; } if (signBeforePrefix && (value.slice(0, 1) == '-')) { var prev = (prevResult.slice(0, 1) == '-') ? prevResult.slice(1) : prevResult; return '-' + this.getPrefixStrippedValue(value.slice(1), prefix, prefixLength, prev, delimiter, delimiters, noImmediatePrefix, tailPrefix, signBeforePrefix); } // Pre result prefix string does not match pre-defined prefix if (prevResult.slice(0, prefixLength) !== prefix && !tailPrefix) { // Check if the first time user entered something if (noImmediatePrefix && !prevResult && value) return value; return ''; } else if (prevResult.slice(-prefixLength) !== prefix && tailPrefix) { // Check if the first time user entered something if (noImmediatePrefix && !prevResult && value) return value; return ''; } var prevValue = this.stripDelimiters(prevResult, delimiter, delimiters); // New value has issue, someone typed in between prefix letters // Revert to pre value if (value.slice(0, prefixLength) !== prefix && !tailPrefix) { return prevValue.slice(prefixLength); } else if (value.slice(-prefixLength) !== prefix && tailPrefix) { return prevValue.slice(0, -prefixLength - 1); } // No issue, strip prefix for new value return tailPrefix ? value.slice(0, -prefixLength) : value.slice(prefixLength); }, getFirstDiffIndex: function (prev, current) { var index = 0; while (prev.charAt(index) === current.charAt(index)) { if (prev.charAt(index++) === '') { return -1; } } return index; }, getFormattedValue: function (value, blocks, blocksLength, delimiter, delimiters, delimiterLazyShow) { var result = '', multipleDelimiters = delimiters.length > 0, currentDelimiter = ''; // no options, normal input if (blocksLength === 0) { return value; } blocks.forEach(function (length, index) { if (value.length > 0) { var sub = value.slice(0, length), rest = value.slice(length); if (multipleDelimiters) { currentDelimiter = delimiters[delimiterLazyShow ? (index - 1) : index] || currentDelimiter; } else { currentDelimiter = delimiter; } if (delimiterLazyShow) { if (index > 0) { result += currentDelimiter; } result += sub; } else { result += sub; if (sub.length === length && index < blocksLength - 1) { result += currentDelimiter; } } // update remaining string value = rest; } }); return result; }, // move cursor to the end // the first time user focuses on an input with prefix fixPrefixCursor: function (el, prefix, delimiter, delimiters) { if (!el) { return; } var val = el.value, appendix = delimiter || (delimiters[0] || ' '); if (!el.setSelectionRange || !prefix || (prefix.length + appendix.length) <= val.length) { return; } var len = val.length * 2; // set timeout to avoid blink setTimeout(function () { el.setSelectionRange(len, len); }, 1); }, // Check if input field is fully selected checkFullSelection: function(value) { try { var selection = window.getSelection() || document.getSelection() || {}; return selection.toString().length === value.length; } catch (ex) { // Ignore } return false; }, setSelection: function (element, position, doc) { if (element !== this.getActiveElement(doc)) { return; } // cursor is already in the end if (element && element.value.length <= position) { return; } if (element.createTextRange) { var range = element.createTextRange(); range.move('character', position); range.select(); } else { try { element.setSelectionRange(position, position); } catch (e) { // eslint-disable-next-line console.warn('The input element type does not support selection'); } } }, getActiveElement: function(parent) { var activeElement = parent.activeElement; if (activeElement && activeElement.shadowRoot) { return this.getActiveElement(activeElement.shadowRoot); } return activeElement; }, isAndroid: function () { return navigator && /android/i.test(navigator.userAgent); }, // On Android chrome, the keyup and keydown events // always return key code 229 as a composition that // buffers the user’s keystrokes // see https://github.com/nosir/cleave.js/issues/147 isAndroidBackspaceKeydown: function (lastInputValue, currentInputValue) { if (!this.isAndroid() || !lastInputValue || !currentInputValue) { return false; } return currentInputValue === lastInputValue.slice(0, -1); } }; var Util_1 = Util; /** * Props Assignment * * Separate this, so react module can share the usage */ var DefaultProperties = { // Maybe change to object-assign // for now just keep it as simple assign: function (target, opts) { target = target || {}; opts = opts || {}; // credit card target.creditCard = !!opts.creditCard; target.creditCardStrictMode = !!opts.creditCardStrictMode; target.creditCardType = ''; target.onCreditCardTypeChanged = opts.onCreditCardTypeChanged || (function () {}); // phone target.phone = !!opts.phone; target.phoneRegionCode = opts.phoneRegionCode || 'AU'; target.phoneFormatter = {}; // time target.time = !!opts.time; target.timePattern = opts.timePattern || ['h', 'm', 's']; target.timeFormat = opts.timeFormat || '24'; target.timeFormatter = {}; // date target.date = !!opts.date; target.datePattern = opts.datePattern || ['d', 'm', 'Y']; target.dateMin = opts.dateMin || ''; target.dateMax = opts.dateMax || ''; target.dateFormatter = {}; // numeral target.numeral = !!opts.numeral; target.numeralIntegerScale = opts.numeralIntegerScale > 0 ? opts.numeralIntegerScale : 0; target.numeralDecimalScale = opts.numeralDecimalScale >= 0 ? opts.numeralDecimalScale : 2; target.numeralDecimalMark = opts.numeralDecimalMark || '.'; target.numeralThousandsGroupStyle = opts.numeralThousandsGroupStyle || 'thousand'; target.numeralPositiveOnly = !!opts.numeralPositiveOnly; target.stripLeadingZeroes = opts.stripLeadingZeroes !== false; target.signBeforePrefix = !!opts.signBeforePrefix; target.tailPrefix = !!opts.tailPrefix; // others target.swapHiddenInput = !!opts.swapHiddenInput; target.numericOnly = target.creditCard || target.date || !!opts.numericOnly; target.uppercase = !!opts.uppercase; target.lowercase = !!opts.lowercase; target.prefix = (target.creditCard || target.date) ? '' : (opts.prefix || ''); target.noImmediatePrefix = !!opts.noImmediatePrefix; target.prefixLength = target.prefix.length; target.rawValueTrimPrefix = !!opts.rawValueTrimPrefix; target.copyDelimiter = !!opts.copyDelimiter; target.initValue = (opts.initValue !== undefined && opts.initValue !== null) ? opts.initValue.toString() : ''; target.delimiter = (opts.delimiter || opts.delimiter === '') ? opts.delimiter : (opts.date ? '/' : (opts.time ? ':' : (opts.numeral ? ',' : (opts.phone ? ' ' : ' ')))); target.delimiterLength = target.delimiter.length; target.delimiterLazyShow = !!opts.delimiterLazyShow; target.delimiters = opts.delimiters || []; target.blocks = opts.blocks || []; target.blocksLength = target.blocks.length; target.root = (typeof commonjsGlobal === 'object' && commonjsGlobal) ? commonjsGlobal : window; target.document = opts.document || target.root.document; target.maxLength = 0; target.backspace = false; target.result = ''; target.onValueChanged = opts.onValueChanged || (function () {}); return target; } }; var DefaultProperties_1 = DefaultProperties; /** * Construct a new Cleave instance by passing the configuration object * * @param {String | HTMLElement} element * @param {Object} opts */ var Cleave = function (element, opts) { var owner = this; var hasMultipleElements = false; if (typeof element === 'string') { owner.element = document.querySelector(element); hasMultipleElements = document.querySelectorAll(element).length > 1; } else { if (typeof element.length !== 'undefined' && element.length > 0) { owner.element = element[0]; hasMultipleElements = element.length > 1; } else { owner.element = element; } } if (!owner.element) { throw new Error('[cleave.js] Please check the element'); } if (hasMultipleElements) { try { // eslint-disable-next-line console.warn('[cleave.js] Multiple input fields matched, cleave.js will only take the first one.'); } catch (e) { // Old IE } } opts.initValue = owner.element.value; owner.properties = Cleave.DefaultProperties.assign({}, opts); owner.init(); }; Cleave.prototype = { init: function () { var owner = this, pps = owner.properties; // no need to use this lib if (!pps.numeral && !pps.phone && !pps.creditCard && !pps.time && !pps.date && (pps.blocksLength === 0 && !pps.prefix)) { owner.onInput(pps.initValue); return; } pps.maxLength = Cleave.Util.getMaxLength(pps.blocks); owner.isAndroid = Cleave.Util.isAndroid(); owner.lastInputValue = ''; owner.isBackward = ''; owner.onChangeListener = owner.onChange.bind(owner); owner.onKeyDownListener = owner.onKeyDown.bind(owner); owner.onFocusListener = owner.onFocus.bind(owner); owner.onCutListener = owner.onCut.bind(owner); owner.onCopyListener = owner.onCopy.bind(owner); owner.initSwapHiddenInput(); owner.element.addEventListener('input', owner.onChangeListener); owner.element.addEventListener('keydown', owner.onKeyDownListener); owner.element.addEventListener('focus', owner.onFocusListener); owner.element.addEventListener('cut', owner.onCutListener); owner.element.addEventListener('copy', owner.onCopyListener); owner.initPhoneFormatter(); owner.initDateFormatter(); owner.initTimeFormatter(); owner.initNumeralFormatter(); // avoid touch input field if value is null // otherwise Firefox will add red box-shadow for if (pps.initValue || (pps.prefix && !pps.noImmediatePrefix)) { owner.onInput(pps.initValue); } }, initSwapHiddenInput: function () { var owner = this, pps = owner.properties; if (!pps.swapHiddenInput) return; var inputFormatter = owner.element.cloneNode(true); owner.element.parentNode.insertBefore(inputFormatter, owner.element); owner.elementSwapHidden = owner.element; owner.elementSwapHidden.type = 'hidden'; owner.element = inputFormatter; owner.element.id = ''; }, initNumeralFormatter: function () { var owner = this, pps = owner.properties; if (!pps.numeral) { return; } pps.numeralFormatter = new Cleave.NumeralFormatter( pps.numeralDecimalMark, pps.numeralIntegerScale, pps.numeralDecimalScale, pps.numeralThousandsGroupStyle, pps.numeralPositiveOnly, pps.stripLeadingZeroes, pps.prefix, pps.signBeforePrefix, pps.tailPrefix, pps.delimiter ); }, initTimeFormatter: function() { var owner = this, pps = owner.properties; if (!pps.time) { return; } pps.timeFormatter = new Cleave.TimeFormatter(pps.timePattern, pps.timeFormat); pps.blocks = pps.timeFormatter.getBlocks(); pps.blocksLength = pps.blocks.length; pps.maxLength = Cleave.Util.getMaxLength(pps.blocks); }, initDateFormatter: function () { var owner = this, pps = owner.properties; if (!pps.date) { return; } pps.dateFormatter = new Cleave.DateFormatter(pps.datePattern, pps.dateMin, pps.dateMax); pps.blocks = pps.dateFormatter.getBlocks(); pps.blocksLength = pps.blocks.length; pps.maxLength = Cleave.Util.getMaxLength(pps.blocks); }, initPhoneFormatter: function () { var owner = this, pps = owner.properties; if (!pps.phone) { return; } // Cleave.AsYouTypeFormatter should be provided by // external google closure lib try { pps.phoneFormatter = new Cleave.PhoneFormatter( new pps.root.Cleave.AsYouTypeFormatter(pps.phoneRegionCode), pps.delimiter ); } catch (ex) { throw new Error('[cleave.js] Please include phone-type-formatter.{country}.js lib'); } }, onKeyDown: function (event) { var owner = this, charCode = event.which || event.keyCode; owner.lastInputValue = owner.element.value; owner.isBackward = charCode === 8; }, onChange: function (event) { var owner = this, pps = owner.properties, Util = Cleave.Util; owner.isBackward = owner.isBackward || event.inputType === 'deleteContentBackward'; var postDelimiter = Util.getPostDelimiter(owner.lastInputValue, pps.delimiter, pps.delimiters); if (owner.isBackward && postDelimiter) { pps.postDelimiterBackspace = postDelimiter; } else { pps.postDelimiterBackspace = false; } this.onInput(this.element.value); }, onFocus: function () { var owner = this, pps = owner.properties; owner.lastInputValue = owner.element.value; if (pps.prefix && pps.noImmediatePrefix && !owner.element.value) { this.onInput(pps.prefix); } Cleave.Util.fixPrefixCursor(owner.element, pps.prefix, pps.delimiter, pps.delimiters); }, onCut: function (e) { if (!Cleave.Util.checkFullSelection(this.element.value)) return; this.copyClipboardData(e); this.onInput(''); }, onCopy: function (e) { if (!Cleave.Util.checkFullSelection(this.element.value)) return; this.copyClipboardData(e); }, copyClipboardData: function (e) { var owner = this, pps = owner.properties, Util = Cleave.Util, inputValue = owner.element.value, textToCopy = ''; if (!pps.copyDelimiter) { textToCopy = Util.stripDelimiters(inputValue, pps.delimiter, pps.delimiters); } else { textToCopy = inputValue; } try { if (e.clipboardData) { e.clipboardData.setData('Text', textToCopy); } else { window.clipboardData.setData('Text', textToCopy); } e.preventDefault(); } catch (ex) { // empty } }, onInput: function (value) { var owner = this, pps = owner.properties, Util = Cleave.Util; // case 1: delete one more character "4" // 1234*| -> hit backspace -> 123| // case 2: last character is not delimiter which is: // 12|34* -> hit backspace -> 1|34* // note: no need to apply this for numeral mode var postDelimiterAfter = Util.getPostDelimiter(value, pps.delimiter, pps.delimiters); if (!pps.numeral && pps.postDelimiterBackspace && !postDelimiterAfter) { value = Util.headStr(value, value.length - pps.postDelimiterBackspace.length); } // phone formatter if (pps.phone) { if (pps.prefix && (!pps.noImmediatePrefix || value.length)) { pps.result = pps.prefix + pps.phoneFormatter.format(value).slice(pps.prefix.length); } else { pps.result = pps.phoneFormatter.format(value); } owner.updateValueState(); return; } // numeral formatter if (pps.numeral) { // Do not show prefix when noImmediatePrefix is specified // This mostly because we need to show user the native input placeholder if (pps.prefix && pps.noImmediatePrefix && value.length === 0) { pps.result = ''; } else { pps.result = pps.numeralFormatter.format(value); } owner.updateValueState(); return; } // date if (pps.date) { value = pps.dateFormatter.getValidatedDate(value); } // time if (pps.time) { value = pps.timeFormatter.getValidatedTime(value); } // strip delimiters value = Util.stripDelimiters(value, pps.delimiter, pps.delimiters); // strip prefix value = Util.getPrefixStrippedValue(value, pps.prefix, pps.prefixLength, pps.result, pps.delimiter, pps.delimiters, pps.noImmediatePrefix, pps.tailPrefix, pps.signBeforePrefix); // strip non-numeric characters value = pps.numericOnly ? Util.strip(value, /[^\d]/g) : value; // convert case value = pps.uppercase ? value.toUpperCase() : value; value = pps.lowercase ? value.toLowerCase() : value; // prevent from showing prefix when no immediate option enabled with empty input value if (pps.prefix) { if (pps.tailPrefix) { value = value + pps.prefix; } else { value = pps.prefix + value; } // no blocks specified, no need to do formatting if (pps.blocksLength === 0) { pps.result = value; owner.updateValueState(); return; } } // update credit card props if (pps.creditCard) { owner.updateCreditCardPropsByValue(value); } // strip over length characters value = Util.headStr(value, pps.maxLength); // apply blocks pps.result = Util.getFormattedValue( value, pps.blocks, pps.blocksLength, pps.delimiter, pps.delimiters, pps.delimiterLazyShow ); owner.updateValueState(); }, updateCreditCardPropsByValue: function (value) { var owner = this, pps = owner.properties, Util = Cleave.Util, creditCardInfo; // At least one of the first 4 characters has changed if (Util.headStr(pps.result, 4) === Util.headStr(value, 4)) { return; } creditCardInfo = Cleave.CreditCardDetector.getInfo(value, pps.creditCardStrictMode); pps.blocks = creditCardInfo.blocks; pps.blocksLength = pps.blocks.length; pps.maxLength = Util.getMaxLength(pps.blocks); // credit card type changed if (pps.creditCardType !== creditCardInfo.type) { pps.creditCardType = creditCardInfo.type; pps.onCreditCardTypeChanged.call(owner, pps.creditCardType); } }, updateValueState: function () { var owner = this, Util = Cleave.Util, pps = owner.properties; if (!owner.element) { return; } var endPos = owner.element.selectionEnd; var oldValue = owner.element.value; var newValue = pps.result; endPos = Util.getNextCursorPosition(endPos, oldValue, newValue, pps.delimiter, pps.delimiters); // fix Android browser type="text" input field // cursor not jumping issue if (owner.isAndroid) { window.setTimeout(function () { owner.element.value = newValue; Util.setSelection(owner.element, endPos, pps.document, false); owner.callOnValueChanged(); }, 1); return; } owner.element.value = newValue; if (pps.swapHiddenInput) owner.elementSwapHidden.value = owner.getRawValue(); Util.setSelection(owner.element, endPos, pps.document, false); owner.callOnValueChanged(); }, callOnValueChanged: function () { var owner = this, pps = owner.properties; pps.onValueChanged.call(owner, { target: { name: owner.element.name, value: pps.result, rawValue: owner.getRawValue() } }); }, setPhoneRegionCode: function (phoneRegionCode) { var owner = this, pps = owner.properties; pps.phoneRegionCode = phoneRegionCode; owner.initPhoneFormatter(); owner.onChange(); }, setRawValue: function (value) { var owner = this, pps = owner.properties; value = value !== undefined && value !== null ? value.toString() : ''; if (pps.numeral) { value = value.replace('.', pps.numeralDecimalMark); } pps.postDelimiterBackspace = false; owner.element.value = value; owner.onInput(value); }, getRawValue: function () { var owner = this, pps = owner.properties, Util = Cleave.Util, rawValue = owner.element.value; if (pps.rawValueTrimPrefix) { rawValue = Util.getPrefixStrippedValue(rawValue, pps.prefix, pps.prefixLength, pps.result, pps.delimiter, pps.delimiters, pps.noImmediatePrefix, pps.tailPrefix, pps.signBeforePrefix); } if (pps.numeral) { rawValue = pps.numeralFormatter.getRawValue(rawValue); } else { rawValue = Util.stripDelimiters(rawValue, pps.delimiter, pps.delimiters); } return rawValue; }, getISOFormatDate: function () { var owner = this, pps = owner.properties; return pps.date ? pps.dateFormatter.getISOFormatDate() : ''; }, getISOFormatTime: function () { var owner = this, pps = owner.properties; return pps.time ? pps.timeFormatter.getISOFormatTime() : ''; }, getFormattedValue: function () { return this.element.value; }, destroy: function () { var owner = this; owner.element.removeEventListener('input', owner.onChangeListener); owner.element.removeEventListener('keydown', owner.onKeyDownListener); owner.element.removeEventListener('focus', owner.onFocusListener); owner.element.removeEventListener('cut', owner.onCutListener); owner.element.removeEventListener('copy', owner.onCopyListener); }, toString: function () { return '[Cleave Object]'; } }; Cleave.NumeralFormatter = NumeralFormatter_1; Cleave.DateFormatter = DateFormatter_1; Cleave.TimeFormatter = TimeFormatter_1; Cleave.PhoneFormatter = PhoneFormatter_1; Cleave.CreditCardDetector = CreditCardDetector_1; Cleave.Util = Util_1; Cleave.DefaultProperties = DefaultProperties_1; // for angular directive ((typeof commonjsGlobal === 'object' && commonjsGlobal) ? commonjsGlobal : window)['Cleave'] = Cleave; // CommonJS var Cleave_1 = Cleave; export default Cleave_1;