1726 lines
55 KiB
JavaScript
1726 lines
55 KiB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
|
||
if(typeof exports === 'object' && typeof module === 'object')
|
||
module.exports = factory();
|
||
else if(typeof define === 'function' && define.amd)
|
||
define([], factory);
|
||
else if(typeof exports === 'object')
|
||
exports["Cleave"] = factory();
|
||
else
|
||
root["Cleave"] = factory();
|
||
})(this, function() {
|
||
return /******/ (function(modules) { // webpackBootstrap
|
||
/******/ // The module cache
|
||
/******/ var installedModules = {};
|
||
|
||
/******/ // The require function
|
||
/******/ function __webpack_require__(moduleId) {
|
||
|
||
/******/ // Check if module is in cache
|
||
/******/ if(installedModules[moduleId])
|
||
/******/ return installedModules[moduleId].exports;
|
||
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = installedModules[moduleId] = {
|
||
/******/ exports: {},
|
||
/******/ id: moduleId,
|
||
/******/ loaded: false
|
||
/******/ };
|
||
|
||
/******/ // Execute the module function
|
||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
|
||
/******/ // Flag the module as loaded
|
||
/******/ module.loaded = true;
|
||
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
|
||
|
||
/******/ // expose the modules object (__webpack_modules__)
|
||
/******/ __webpack_require__.m = modules;
|
||
|
||
/******/ // expose the module cache
|
||
/******/ __webpack_require__.c = installedModules;
|
||
|
||
/******/ // __webpack_public_path__
|
||
/******/ __webpack_require__.p = "";
|
||
|
||
/******/ // Load entry module and return exports
|
||
/******/ return __webpack_require__(0);
|
||
/******/ })
|
||
/************************************************************************/
|
||
/******/ ([
|
||
/* 0 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
|
||
|
||
/**
|
||
* 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 <input required />
|
||
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 = __webpack_require__(1);
|
||
Cleave.DateFormatter = __webpack_require__(2);
|
||
Cleave.TimeFormatter = __webpack_require__(3);
|
||
Cleave.PhoneFormatter = __webpack_require__(4);
|
||
Cleave.CreditCardDetector = __webpack_require__(5);
|
||
Cleave.Util = __webpack_require__(6);
|
||
Cleave.DefaultProperties = __webpack_require__(7);
|
||
|
||
// for angular directive
|
||
((typeof global === 'object' && global) ? global : window)['Cleave'] = Cleave;
|
||
|
||
// CommonJS
|
||
module.exports = Cleave;
|
||
|
||
angular.module('cleave.js', [])
|
||
.directive('cleave', function () {
|
||
return {
|
||
restrict: 'A',
|
||
require: 'ngModel',
|
||
|
||
scope: {
|
||
cleave: '&',
|
||
onInit: '&?',
|
||
onValueChange: '&?'
|
||
},
|
||
|
||
compile: function () {
|
||
return {
|
||
pre: function ($scope, $element, attrs, ngModelCtrl) {
|
||
// eslint-disable-next-line
|
||
$scope.instance = new Cleave($element[0], $scope.cleave());
|
||
|
||
if ($scope.onInit) {
|
||
$scope.onInit()($scope.instance);
|
||
}
|
||
|
||
ngModelCtrl.$formatters.push(function (val) {
|
||
$scope.instance.setRawValue(val);
|
||
|
||
return $scope.instance.getFormattedValue();
|
||
});
|
||
|
||
ngModelCtrl.$parsers.push(function (newFormattedValue) {
|
||
if ($scope.onValueChange) {
|
||
$scope.onValueChange()(newFormattedValue);
|
||
}
|
||
|
||
return $scope.instance.getRawValue();
|
||
});
|
||
|
||
// Recreate cleave instance if any cleave options change
|
||
$scope.$watch(function() {
|
||
return $scope.cleave();
|
||
// eslint-disable-next-line
|
||
}, function (newOptions, oldOptions) {
|
||
$scope.instance.destroy();
|
||
// eslint-disable-next-line
|
||
$scope.instance = new Cleave($element[0], newOptions);
|
||
}, true);
|
||
|
||
$scope.$on('$destroy', function () {
|
||
|
||
$scope.instance.destroy();
|
||
$scope.instance = null;
|
||
});
|
||
}
|
||
};
|
||
}
|
||
};
|
||
});
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
|
||
|
||
/***/ }),
|
||
/* 1 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
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() : '');
|
||
}
|
||
};
|
||
|
||
module.exports = NumeralFormatter;
|
||
|
||
|
||
/***/ }),
|
||
/* 2 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
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;
|
||
}
|
||
};
|
||
|
||
module.exports = DateFormatter;
|
||
|
||
|
||
/***/ }),
|
||
/* 3 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
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;
|
||
}
|
||
};
|
||
|
||
module.exports = TimeFormatter;
|
||
|
||
|
||
/***/ }),
|
||
/* 4 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
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;
|
||
}
|
||
};
|
||
|
||
module.exports = PhoneFormatter;
|
||
|
||
|
||
/***/ }),
|
||
/* 5 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
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
|
||
};
|
||
}
|
||
};
|
||
|
||
module.exports = CreditCardDetector;
|
||
|
||
|
||
/***/ }),
|
||
/* 6 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
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);
|
||
}
|
||
};
|
||
|
||
module.exports = Util;
|
||
|
||
|
||
/***/ }),
|
||
/* 7 */
|
||
/***/ (function(module, exports) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(global) {'use strict';
|
||
|
||
/**
|
||
* 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 global === 'object' && global) ? global : window;
|
||
target.document = opts.document || target.root.document;
|
||
|
||
target.maxLength = 0;
|
||
|
||
target.backspace = false;
|
||
target.result = '';
|
||
|
||
target.onValueChanged = opts.onValueChanged || (function () {});
|
||
|
||
return target;
|
||
}
|
||
};
|
||
|
||
module.exports = DefaultProperties;
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
|
||
|
||
/***/ })
|
||
/******/ ])
|
||
});
|
||
; |