2891 lines
92 KiB
JavaScript
2891 lines
92 KiB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
|
||
if(typeof exports === 'object' && typeof module === 'object')
|
||
module.exports = factory(require("react"));
|
||
else if(typeof define === 'function' && define.amd)
|
||
define(["react"], factory);
|
||
else if(typeof exports === 'object')
|
||
exports["Cleave"] = factory(require("react"));
|
||
else
|
||
root["Cleave"] = factory(root["React"]);
|
||
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {
|
||
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__) {
|
||
|
||
'use strict';
|
||
|
||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||
|
||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
||
|
||
var React = __webpack_require__(1); // eslint-disable-line no-unused-vars
|
||
var CreateReactClass = __webpack_require__(2);
|
||
|
||
var NumeralFormatter = __webpack_require__(9);
|
||
var DateFormatter = __webpack_require__(10);
|
||
var TimeFormatter = __webpack_require__(11);
|
||
var PhoneFormatter = __webpack_require__(12);
|
||
var CreditCardDetector = __webpack_require__(13);
|
||
var Util = __webpack_require__(14);
|
||
var DefaultProperties = __webpack_require__(15);
|
||
|
||
var cleaveReactClass = CreateReactClass({
|
||
componentDidMount: function componentDidMount() {
|
||
this.init();
|
||
},
|
||
|
||
componentDidUpdate: function componentDidUpdate(prevProps) {
|
||
var owner = this,
|
||
phoneRegionCode = (owner.props.options || {}).phoneRegionCode,
|
||
newValue = owner.props.value,
|
||
pps = owner.properties;
|
||
|
||
owner.updateRegisteredEvents(owner.props);
|
||
if (prevProps.value !== newValue && newValue !== undefined && newValue !== null) {
|
||
newValue = newValue.toString();
|
||
|
||
if (newValue !== owner.properties.result) {
|
||
owner.properties.initValue = newValue;
|
||
owner.onInput(newValue, true);
|
||
}
|
||
}
|
||
|
||
// update phone region code
|
||
var prevPhoneRegionCode = (prevProps.options || {}).phoneRegionCode;
|
||
if (prevPhoneRegionCode !== phoneRegionCode && phoneRegionCode && phoneRegionCode !== owner.properties.phoneRegionCode) {
|
||
owner.properties.phoneRegionCode = phoneRegionCode;
|
||
owner.initPhoneFormatter();
|
||
owner.onInput(owner.properties.result);
|
||
}
|
||
|
||
Util.setSelection(owner.element, owner.state.cursorPosition, pps.document);
|
||
},
|
||
|
||
updateRegisteredEvents: function updateRegisteredEvents(props) {
|
||
var owner = this,
|
||
_owner$registeredEven = owner.registeredEvents,
|
||
onKeyDown = _owner$registeredEven.onKeyDown,
|
||
onChange = _owner$registeredEven.onChange,
|
||
onFocus = _owner$registeredEven.onFocus,
|
||
onBlur = _owner$registeredEven.onBlur,
|
||
onInit = _owner$registeredEven.onInit;
|
||
|
||
|
||
if (props.onInit && props.onInit !== onInit) owner.registeredEvents.onInit = props.onInit;
|
||
if (props.onChange && props.onChange !== onChange) owner.registeredEvents.onChange = props.onChange;
|
||
if (props.onFocus && props.onFocus !== onFocus) owner.registeredEvents.onFocus = props.onFocus;
|
||
if (props.onBlur && props.onBlur !== onBlur) owner.registeredEvents.onBlur = props.onBlur;
|
||
if (props.onKeyDown && props.onKeyDown !== onKeyDown) owner.registeredEvents.onKeyDown = props.onKeyDown;
|
||
},
|
||
|
||
getInitialState: function getInitialState() {
|
||
var owner = this,
|
||
_owner$props = owner.props,
|
||
value = _owner$props.value,
|
||
options = _owner$props.options,
|
||
onKeyDown = _owner$props.onKeyDown,
|
||
onChange = _owner$props.onChange,
|
||
onFocus = _owner$props.onFocus,
|
||
onBlur = _owner$props.onBlur,
|
||
onInit = _owner$props.onInit;
|
||
|
||
|
||
owner.registeredEvents = {
|
||
onInit: onInit || Util.noop,
|
||
onChange: onChange || Util.noop,
|
||
onFocus: onFocus || Util.noop,
|
||
onBlur: onBlur || Util.noop,
|
||
onKeyDown: onKeyDown || Util.noop
|
||
};
|
||
|
||
if (!options) {
|
||
options = {};
|
||
}
|
||
|
||
options.initValue = value;
|
||
|
||
owner.properties = DefaultProperties.assign({}, options);
|
||
|
||
return {
|
||
value: owner.properties.result,
|
||
cursorPosition: 0
|
||
};
|
||
},
|
||
|
||
init: function init() {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
// so no need for this lib at all
|
||
if (!pps.numeral && !pps.phone && !pps.creditCard && !pps.time && !pps.date && pps.blocksLength === 0 && !pps.prefix) {
|
||
owner.onInput(pps.initValue);
|
||
owner.registeredEvents.onInit(owner);
|
||
|
||
return;
|
||
}
|
||
|
||
pps.maxLength = Util.getMaxLength(pps.blocks);
|
||
|
||
owner.isAndroid = Util.isAndroid();
|
||
|
||
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);
|
||
}
|
||
|
||
owner.registeredEvents.onInit(owner);
|
||
},
|
||
|
||
initNumeralFormatter: function initNumeralFormatter() {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
if (!pps.numeral) {
|
||
return;
|
||
}
|
||
|
||
pps.numeralFormatter = new NumeralFormatter(pps.numeralDecimalMark, pps.numeralIntegerScale, pps.numeralDecimalScale, pps.numeralThousandsGroupStyle, pps.numeralPositiveOnly, pps.stripLeadingZeroes, pps.prefix, pps.signBeforePrefix, pps.tailPrefix, pps.delimiter);
|
||
},
|
||
|
||
initTimeFormatter: function initTimeFormatter() {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
if (!pps.time) {
|
||
return;
|
||
}
|
||
|
||
pps.timeFormatter = new TimeFormatter(pps.timePattern, pps.timeFormat);
|
||
pps.blocks = pps.timeFormatter.getBlocks();
|
||
pps.blocksLength = pps.blocks.length;
|
||
pps.maxLength = Util.getMaxLength(pps.blocks);
|
||
},
|
||
|
||
initDateFormatter: function initDateFormatter() {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
if (!pps.date) {
|
||
return;
|
||
}
|
||
|
||
pps.dateFormatter = new DateFormatter(pps.datePattern, pps.dateMin, pps.dateMax);
|
||
pps.blocks = pps.dateFormatter.getBlocks();
|
||
pps.blocksLength = pps.blocks.length;
|
||
pps.maxLength = Util.getMaxLength(pps.blocks);
|
||
},
|
||
|
||
initPhoneFormatter: function initPhoneFormatter() {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
if (!pps.phone) {
|
||
return;
|
||
}
|
||
|
||
// Cleave.AsYouTypeFormatter should be provided by
|
||
// external google closure lib
|
||
try {
|
||
pps.phoneFormatter = new PhoneFormatter(new pps.root.Cleave.AsYouTypeFormatter(pps.phoneRegionCode), pps.delimiter);
|
||
} catch (ex) {
|
||
throw new Error('Please include phone-type-formatter.{country}.js lib');
|
||
}
|
||
},
|
||
|
||
setRawValue: function setRawValue(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.onChange({
|
||
target: { value: value },
|
||
|
||
// Methods to better resemble a SyntheticEvent
|
||
stopPropagation: Util.noop,
|
||
preventDefault: Util.noop,
|
||
persist: Util.noop
|
||
});
|
||
},
|
||
|
||
getRawValue: function getRawValue() {
|
||
var owner = this,
|
||
pps = owner.properties,
|
||
rawValue = pps.result;
|
||
|
||
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 ? pps.numeralFormatter.getRawValue(rawValue) : '';
|
||
} else {
|
||
rawValue = Util.stripDelimiters(rawValue, pps.delimiter, pps.delimiters);
|
||
}
|
||
|
||
return rawValue;
|
||
},
|
||
|
||
getISOFormatDate: function getISOFormatDate() {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
return pps.date ? pps.dateFormatter.getISOFormatDate() : '';
|
||
},
|
||
|
||
getISOFormatTime: function getISOFormatTime() {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
return pps.time ? pps.timeFormatter.getISOFormatTime() : '';
|
||
},
|
||
|
||
onInit: function onInit(owner) {
|
||
return owner;
|
||
},
|
||
|
||
onKeyDown: function onKeyDown(event) {
|
||
var owner = this,
|
||
pps = owner.properties,
|
||
charCode = event.which || event.keyCode;
|
||
|
||
owner.lastInputValue = pps.result;
|
||
owner.isBackward = charCode === 8;
|
||
|
||
owner.registeredEvents.onKeyDown(event);
|
||
},
|
||
|
||
onFocus: function onFocus(event) {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
if (pps.prefix && pps.noImmediatePrefix && !event.target.value) {
|
||
owner.onInput(pps.prefix);
|
||
}
|
||
|
||
event.target.rawValue = owner.getRawValue();
|
||
event.target.value = pps.result;
|
||
|
||
owner.registeredEvents.onFocus(event);
|
||
|
||
Util.fixPrefixCursor(owner.element, pps.prefix, pps.delimiter, pps.delimiters);
|
||
},
|
||
|
||
onBlur: function onBlur(event) {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
event.target.rawValue = owner.getRawValue();
|
||
event.target.value = pps.result;
|
||
|
||
owner.registeredEvents.onBlur(event);
|
||
},
|
||
|
||
onChange: function onChange(event) {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
owner.isBackward = owner.isBackward || event.inputType === 'deleteContentBackward';
|
||
// hit backspace when last character is delimiter
|
||
var postDelimiter = Util.getPostDelimiter(owner.lastInputValue, pps.delimiter, pps.delimiters);
|
||
|
||
if (owner.isBackward && postDelimiter) {
|
||
pps.postDelimiterBackspace = postDelimiter;
|
||
} else {
|
||
pps.postDelimiterBackspace = false;
|
||
}
|
||
|
||
owner.onInput(event.target.value);
|
||
|
||
event.target.rawValue = owner.getRawValue();
|
||
event.target.value = pps.result;
|
||
|
||
owner.registeredEvents.onChange(event);
|
||
},
|
||
|
||
onInput: function onInput(value, fromProps) {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
// 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*
|
||
var postDelimiterAfter = Util.getPostDelimiter(value, pps.delimiter, pps.delimiters);
|
||
if (!fromProps && !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 = pps.maxLength > 0 ? Util.headStr(value, pps.maxLength) : value;
|
||
|
||
// apply blocks
|
||
pps.result = Util.getFormattedValue(value, pps.blocks, pps.blocksLength, pps.delimiter, pps.delimiters, pps.delimiterLazyShow);
|
||
|
||
owner.updateValueState();
|
||
},
|
||
|
||
updateCreditCardPropsByValue: function updateCreditCardPropsByValue(value) {
|
||
var owner = this,
|
||
pps = owner.properties,
|
||
creditCardInfo;
|
||
|
||
// At least one of the first 4 characters has changed
|
||
if (Util.headStr(pps.result, 4) === Util.headStr(value, 4)) {
|
||
return;
|
||
}
|
||
|
||
creditCardInfo = 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 updateValueState() {
|
||
var owner = this,
|
||
pps = owner.properties;
|
||
|
||
if (!owner.element) {
|
||
owner.setState({ value: pps.result });
|
||
return;
|
||
}
|
||
|
||
var endPos = owner.element.selectionEnd;
|
||
var oldValue = owner.element.value;
|
||
var newValue = pps.result;
|
||
|
||
owner.lastInputValue = newValue;
|
||
|
||
endPos = Util.getNextCursorPosition(endPos, oldValue, newValue, pps.delimiter, pps.delimiters);
|
||
|
||
if (owner.isAndroid) {
|
||
window.setTimeout(function () {
|
||
owner.setState({ value: newValue, cursorPosition: endPos });
|
||
}, 1);
|
||
|
||
return;
|
||
}
|
||
|
||
owner.setState({ value: newValue, cursorPosition: endPos });
|
||
},
|
||
|
||
render: function render() {
|
||
var owner = this;
|
||
// eslint-disable-next-line
|
||
|
||
var _owner$props2 = owner.props,
|
||
value = _owner$props2.value,
|
||
options = _owner$props2.options,
|
||
onKeyDown = _owner$props2.onKeyDown,
|
||
onFocus = _owner$props2.onFocus,
|
||
onBlur = _owner$props2.onBlur,
|
||
onChange = _owner$props2.onChange,
|
||
onInit = _owner$props2.onInit,
|
||
htmlRef = _owner$props2.htmlRef,
|
||
propsToTransfer = _objectWithoutProperties(_owner$props2, ['value', 'options', 'onKeyDown', 'onFocus', 'onBlur', 'onChange', 'onInit', 'htmlRef']);
|
||
|
||
return React.createElement('input', _extends({
|
||
type: 'text',
|
||
ref: function ref(_ref) {
|
||
owner.element = _ref;
|
||
|
||
if (!htmlRef) {
|
||
return;
|
||
}
|
||
|
||
htmlRef.apply(this, arguments);
|
||
},
|
||
value: owner.state.value,
|
||
onKeyDown: owner.onKeyDown,
|
||
onChange: owner.onChange,
|
||
onFocus: owner.onFocus,
|
||
onBlur: owner.onBlur
|
||
}, propsToTransfer));
|
||
}
|
||
});
|
||
|
||
module.exports = cleaveReactClass;
|
||
|
||
/***/ }),
|
||
/* 1 */
|
||
/***/ (function(module, exports) {
|
||
|
||
module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
|
||
|
||
/***/ }),
|
||
/* 2 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/**
|
||
* Copyright (c) 2013-present, Facebook, Inc.
|
||
*
|
||
* This source code is licensed under the MIT license found in the
|
||
* LICENSE file in the root directory of this source tree.
|
||
*
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
var React = __webpack_require__(1);
|
||
var factory = __webpack_require__(3);
|
||
|
||
if (typeof React === 'undefined') {
|
||
throw Error(
|
||
'create-react-class could not find the React object. If you are using script tags, ' +
|
||
'make sure that React is being loaded before create-react-class.'
|
||
);
|
||
}
|
||
|
||
// Hack to grab NoopUpdateQueue from isomorphic React
|
||
var ReactNoopUpdateQueue = new React.Component().updater;
|
||
|
||
module.exports = factory(
|
||
React.Component,
|
||
React.isValidElement,
|
||
ReactNoopUpdateQueue
|
||
);
|
||
|
||
|
||
/***/ }),
|
||
/* 3 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/**
|
||
* Copyright (c) 2013-present, Facebook, Inc.
|
||
*
|
||
* This source code is licensed under the MIT license found in the
|
||
* LICENSE file in the root directory of this source tree.
|
||
*
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
var _assign = __webpack_require__(4);
|
||
|
||
var emptyObject = __webpack_require__(5);
|
||
var _invariant = __webpack_require__(6);
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
var warning = __webpack_require__(7);
|
||
}
|
||
|
||
var MIXINS_KEY = 'mixins';
|
||
|
||
// Helper function to allow the creation of anonymous functions which do not
|
||
// have .name set to the name of the variable being assigned to.
|
||
function identity(fn) {
|
||
return fn;
|
||
}
|
||
|
||
var ReactPropTypeLocationNames;
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
ReactPropTypeLocationNames = {
|
||
prop: 'prop',
|
||
context: 'context',
|
||
childContext: 'child context'
|
||
};
|
||
} else {
|
||
ReactPropTypeLocationNames = {};
|
||
}
|
||
|
||
function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
|
||
/**
|
||
* Policies that describe methods in `ReactClassInterface`.
|
||
*/
|
||
|
||
var injectedMixins = [];
|
||
|
||
/**
|
||
* Composite components are higher-level components that compose other composite
|
||
* or host components.
|
||
*
|
||
* To create a new type of `ReactClass`, pass a specification of
|
||
* your new class to `React.createClass`. The only requirement of your class
|
||
* specification is that you implement a `render` method.
|
||
*
|
||
* var MyComponent = React.createClass({
|
||
* render: function() {
|
||
* return <div>Hello World</div>;
|
||
* }
|
||
* });
|
||
*
|
||
* The class specification supports a specific protocol of methods that have
|
||
* special meaning (e.g. `render`). See `ReactClassInterface` for
|
||
* more the comprehensive protocol. Any other properties and methods in the
|
||
* class specification will be available on the prototype.
|
||
*
|
||
* @interface ReactClassInterface
|
||
* @internal
|
||
*/
|
||
var ReactClassInterface = {
|
||
/**
|
||
* An array of Mixin objects to include when defining your component.
|
||
*
|
||
* @type {array}
|
||
* @optional
|
||
*/
|
||
mixins: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* An object containing properties and methods that should be defined on
|
||
* the component's constructor instead of its prototype (static methods).
|
||
*
|
||
* @type {object}
|
||
* @optional
|
||
*/
|
||
statics: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Definition of prop types for this component.
|
||
*
|
||
* @type {object}
|
||
* @optional
|
||
*/
|
||
propTypes: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Definition of context types for this component.
|
||
*
|
||
* @type {object}
|
||
* @optional
|
||
*/
|
||
contextTypes: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Definition of context types this component sets for its children.
|
||
*
|
||
* @type {object}
|
||
* @optional
|
||
*/
|
||
childContextTypes: 'DEFINE_MANY',
|
||
|
||
// ==== Definition methods ====
|
||
|
||
/**
|
||
* Invoked when the component is mounted. Values in the mapping will be set on
|
||
* `this.props` if that prop is not specified (i.e. using an `in` check).
|
||
*
|
||
* This method is invoked before `getInitialState` and therefore cannot rely
|
||
* on `this.state` or use `this.setState`.
|
||
*
|
||
* @return {object}
|
||
* @optional
|
||
*/
|
||
getDefaultProps: 'DEFINE_MANY_MERGED',
|
||
|
||
/**
|
||
* Invoked once before the component is mounted. The return value will be used
|
||
* as the initial value of `this.state`.
|
||
*
|
||
* getInitialState: function() {
|
||
* return {
|
||
* isOn: false,
|
||
* fooBaz: new BazFoo()
|
||
* }
|
||
* }
|
||
*
|
||
* @return {object}
|
||
* @optional
|
||
*/
|
||
getInitialState: 'DEFINE_MANY_MERGED',
|
||
|
||
/**
|
||
* @return {object}
|
||
* @optional
|
||
*/
|
||
getChildContext: 'DEFINE_MANY_MERGED',
|
||
|
||
/**
|
||
* Uses props from `this.props` and state from `this.state` to render the
|
||
* structure of the component.
|
||
*
|
||
* No guarantees are made about when or how often this method is invoked, so
|
||
* it must not have side effects.
|
||
*
|
||
* render: function() {
|
||
* var name = this.props.name;
|
||
* return <div>Hello, {name}!</div>;
|
||
* }
|
||
*
|
||
* @return {ReactComponent}
|
||
* @required
|
||
*/
|
||
render: 'DEFINE_ONCE',
|
||
|
||
// ==== Delegate methods ====
|
||
|
||
/**
|
||
* Invoked when the component is initially created and about to be mounted.
|
||
* This may have side effects, but any external subscriptions or data created
|
||
* by this method must be cleaned up in `componentWillUnmount`.
|
||
*
|
||
* @optional
|
||
*/
|
||
componentWillMount: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Invoked when the component has been mounted and has a DOM representation.
|
||
* However, there is no guarantee that the DOM node is in the document.
|
||
*
|
||
* Use this as an opportunity to operate on the DOM when the component has
|
||
* been mounted (initialized and rendered) for the first time.
|
||
*
|
||
* @param {DOMElement} rootNode DOM element representing the component.
|
||
* @optional
|
||
*/
|
||
componentDidMount: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Invoked before the component receives new props.
|
||
*
|
||
* Use this as an opportunity to react to a prop transition by updating the
|
||
* state using `this.setState`. Current props are accessed via `this.props`.
|
||
*
|
||
* componentWillReceiveProps: function(nextProps, nextContext) {
|
||
* this.setState({
|
||
* likesIncreasing: nextProps.likeCount > this.props.likeCount
|
||
* });
|
||
* }
|
||
*
|
||
* NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
|
||
* transition may cause a state change, but the opposite is not true. If you
|
||
* need it, you are probably looking for `componentWillUpdate`.
|
||
*
|
||
* @param {object} nextProps
|
||
* @optional
|
||
*/
|
||
componentWillReceiveProps: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Invoked while deciding if the component should be updated as a result of
|
||
* receiving new props, state and/or context.
|
||
*
|
||
* Use this as an opportunity to `return false` when you're certain that the
|
||
* transition to the new props/state/context will not require a component
|
||
* update.
|
||
*
|
||
* shouldComponentUpdate: function(nextProps, nextState, nextContext) {
|
||
* return !equal(nextProps, this.props) ||
|
||
* !equal(nextState, this.state) ||
|
||
* !equal(nextContext, this.context);
|
||
* }
|
||
*
|
||
* @param {object} nextProps
|
||
* @param {?object} nextState
|
||
* @param {?object} nextContext
|
||
* @return {boolean} True if the component should update.
|
||
* @optional
|
||
*/
|
||
shouldComponentUpdate: 'DEFINE_ONCE',
|
||
|
||
/**
|
||
* Invoked when the component is about to update due to a transition from
|
||
* `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`
|
||
* and `nextContext`.
|
||
*
|
||
* Use this as an opportunity to perform preparation before an update occurs.
|
||
*
|
||
* NOTE: You **cannot** use `this.setState()` in this method.
|
||
*
|
||
* @param {object} nextProps
|
||
* @param {?object} nextState
|
||
* @param {?object} nextContext
|
||
* @param {ReactReconcileTransaction} transaction
|
||
* @optional
|
||
*/
|
||
componentWillUpdate: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Invoked when the component's DOM representation has been updated.
|
||
*
|
||
* Use this as an opportunity to operate on the DOM when the component has
|
||
* been updated.
|
||
*
|
||
* @param {object} prevProps
|
||
* @param {?object} prevState
|
||
* @param {?object} prevContext
|
||
* @param {DOMElement} rootNode DOM element representing the component.
|
||
* @optional
|
||
*/
|
||
componentDidUpdate: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Invoked when the component is about to be removed from its parent and have
|
||
* its DOM representation destroyed.
|
||
*
|
||
* Use this as an opportunity to deallocate any external resources.
|
||
*
|
||
* NOTE: There is no `componentDidUnmount` since your component will have been
|
||
* destroyed by that point.
|
||
*
|
||
* @optional
|
||
*/
|
||
componentWillUnmount: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Replacement for (deprecated) `componentWillMount`.
|
||
*
|
||
* @optional
|
||
*/
|
||
UNSAFE_componentWillMount: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Replacement for (deprecated) `componentWillReceiveProps`.
|
||
*
|
||
* @optional
|
||
*/
|
||
UNSAFE_componentWillReceiveProps: 'DEFINE_MANY',
|
||
|
||
/**
|
||
* Replacement for (deprecated) `componentWillUpdate`.
|
||
*
|
||
* @optional
|
||
*/
|
||
UNSAFE_componentWillUpdate: 'DEFINE_MANY',
|
||
|
||
// ==== Advanced methods ====
|
||
|
||
/**
|
||
* Updates the component's currently mounted DOM representation.
|
||
*
|
||
* By default, this implements React's rendering and reconciliation algorithm.
|
||
* Sophisticated clients may wish to override this.
|
||
*
|
||
* @param {ReactReconcileTransaction} transaction
|
||
* @internal
|
||
* @overridable
|
||
*/
|
||
updateComponent: 'OVERRIDE_BASE'
|
||
};
|
||
|
||
/**
|
||
* Similar to ReactClassInterface but for static methods.
|
||
*/
|
||
var ReactClassStaticInterface = {
|
||
/**
|
||
* This method is invoked after a component is instantiated and when it
|
||
* receives new props. Return an object to update state in response to
|
||
* prop changes. Return null to indicate no change to state.
|
||
*
|
||
* If an object is returned, its keys will be merged into the existing state.
|
||
*
|
||
* @return {object || null}
|
||
* @optional
|
||
*/
|
||
getDerivedStateFromProps: 'DEFINE_MANY_MERGED'
|
||
};
|
||
|
||
/**
|
||
* Mapping from class specification keys to special processing functions.
|
||
*
|
||
* Although these are declared like instance properties in the specification
|
||
* when defining classes using `React.createClass`, they are actually static
|
||
* and are accessible on the constructor instead of the prototype. Despite
|
||
* being static, they must be defined outside of the "statics" key under
|
||
* which all other static methods are defined.
|
||
*/
|
||
var RESERVED_SPEC_KEYS = {
|
||
displayName: function(Constructor, displayName) {
|
||
Constructor.displayName = displayName;
|
||
},
|
||
mixins: function(Constructor, mixins) {
|
||
if (mixins) {
|
||
for (var i = 0; i < mixins.length; i++) {
|
||
mixSpecIntoComponent(Constructor, mixins[i]);
|
||
}
|
||
}
|
||
},
|
||
childContextTypes: function(Constructor, childContextTypes) {
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
validateTypeDef(Constructor, childContextTypes, 'childContext');
|
||
}
|
||
Constructor.childContextTypes = _assign(
|
||
{},
|
||
Constructor.childContextTypes,
|
||
childContextTypes
|
||
);
|
||
},
|
||
contextTypes: function(Constructor, contextTypes) {
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
validateTypeDef(Constructor, contextTypes, 'context');
|
||
}
|
||
Constructor.contextTypes = _assign(
|
||
{},
|
||
Constructor.contextTypes,
|
||
contextTypes
|
||
);
|
||
},
|
||
/**
|
||
* Special case getDefaultProps which should move into statics but requires
|
||
* automatic merging.
|
||
*/
|
||
getDefaultProps: function(Constructor, getDefaultProps) {
|
||
if (Constructor.getDefaultProps) {
|
||
Constructor.getDefaultProps = createMergedResultFunction(
|
||
Constructor.getDefaultProps,
|
||
getDefaultProps
|
||
);
|
||
} else {
|
||
Constructor.getDefaultProps = getDefaultProps;
|
||
}
|
||
},
|
||
propTypes: function(Constructor, propTypes) {
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
validateTypeDef(Constructor, propTypes, 'prop');
|
||
}
|
||
Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes);
|
||
},
|
||
statics: function(Constructor, statics) {
|
||
mixStaticSpecIntoComponent(Constructor, statics);
|
||
},
|
||
autobind: function() {}
|
||
};
|
||
|
||
function validateTypeDef(Constructor, typeDef, location) {
|
||
for (var propName in typeDef) {
|
||
if (typeDef.hasOwnProperty(propName)) {
|
||
// use a warning instead of an _invariant so components
|
||
// don't show up in prod but only in __DEV__
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
warning(
|
||
typeof typeDef[propName] === 'function',
|
||
'%s: %s type `%s` is invalid; it must be a function, usually from ' +
|
||
'React.PropTypes.',
|
||
Constructor.displayName || 'ReactClass',
|
||
ReactPropTypeLocationNames[location],
|
||
propName
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function validateMethodOverride(isAlreadyDefined, name) {
|
||
var specPolicy = ReactClassInterface.hasOwnProperty(name)
|
||
? ReactClassInterface[name]
|
||
: null;
|
||
|
||
// Disallow overriding of base class methods unless explicitly allowed.
|
||
if (ReactClassMixin.hasOwnProperty(name)) {
|
||
_invariant(
|
||
specPolicy === 'OVERRIDE_BASE',
|
||
'ReactClassInterface: You are attempting to override ' +
|
||
'`%s` from your class specification. Ensure that your method names ' +
|
||
'do not overlap with React methods.',
|
||
name
|
||
);
|
||
}
|
||
|
||
// Disallow defining methods more than once unless explicitly allowed.
|
||
if (isAlreadyDefined) {
|
||
_invariant(
|
||
specPolicy === 'DEFINE_MANY' || specPolicy === 'DEFINE_MANY_MERGED',
|
||
'ReactClassInterface: You are attempting to define ' +
|
||
'`%s` on your component more than once. This conflict may be due ' +
|
||
'to a mixin.',
|
||
name
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Mixin helper which handles policy validation and reserved
|
||
* specification keys when building React classes.
|
||
*/
|
||
function mixSpecIntoComponent(Constructor, spec) {
|
||
if (!spec) {
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
var typeofSpec = typeof spec;
|
||
var isMixinValid = typeofSpec === 'object' && spec !== null;
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
warning(
|
||
isMixinValid,
|
||
"%s: You're attempting to include a mixin that is either null " +
|
||
'or not an object. Check the mixins included by the component, ' +
|
||
'as well as any mixins they include themselves. ' +
|
||
'Expected object but got %s.',
|
||
Constructor.displayName || 'ReactClass',
|
||
spec === null ? null : typeofSpec
|
||
);
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
_invariant(
|
||
typeof spec !== 'function',
|
||
"ReactClass: You're attempting to " +
|
||
'use a component class or function as a mixin. Instead, just use a ' +
|
||
'regular object.'
|
||
);
|
||
_invariant(
|
||
!isValidElement(spec),
|
||
"ReactClass: You're attempting to " +
|
||
'use a component as a mixin. Instead, just use a regular object.'
|
||
);
|
||
|
||
var proto = Constructor.prototype;
|
||
var autoBindPairs = proto.__reactAutoBindPairs;
|
||
|
||
// By handling mixins before any other properties, we ensure the same
|
||
// chaining order is applied to methods with DEFINE_MANY policy, whether
|
||
// mixins are listed before or after these methods in the spec.
|
||
if (spec.hasOwnProperty(MIXINS_KEY)) {
|
||
RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins);
|
||
}
|
||
|
||
for (var name in spec) {
|
||
if (!spec.hasOwnProperty(name)) {
|
||
continue;
|
||
}
|
||
|
||
if (name === MIXINS_KEY) {
|
||
// We have already handled mixins in a special case above.
|
||
continue;
|
||
}
|
||
|
||
var property = spec[name];
|
||
var isAlreadyDefined = proto.hasOwnProperty(name);
|
||
validateMethodOverride(isAlreadyDefined, name);
|
||
|
||
if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
|
||
RESERVED_SPEC_KEYS[name](Constructor, property);
|
||
} else {
|
||
// Setup methods on prototype:
|
||
// The following member methods should not be automatically bound:
|
||
// 1. Expected ReactClass methods (in the "interface").
|
||
// 2. Overridden methods (that were mixed in).
|
||
var isReactClassMethod = ReactClassInterface.hasOwnProperty(name);
|
||
var isFunction = typeof property === 'function';
|
||
var shouldAutoBind =
|
||
isFunction &&
|
||
!isReactClassMethod &&
|
||
!isAlreadyDefined &&
|
||
spec.autobind !== false;
|
||
|
||
if (shouldAutoBind) {
|
||
autoBindPairs.push(name, property);
|
||
proto[name] = property;
|
||
} else {
|
||
if (isAlreadyDefined) {
|
||
var specPolicy = ReactClassInterface[name];
|
||
|
||
// These cases should already be caught by validateMethodOverride.
|
||
_invariant(
|
||
isReactClassMethod &&
|
||
(specPolicy === 'DEFINE_MANY_MERGED' ||
|
||
specPolicy === 'DEFINE_MANY'),
|
||
'ReactClass: Unexpected spec policy %s for key %s ' +
|
||
'when mixing in component specs.',
|
||
specPolicy,
|
||
name
|
||
);
|
||
|
||
// For methods which are defined more than once, call the existing
|
||
// methods before calling the new property, merging if appropriate.
|
||
if (specPolicy === 'DEFINE_MANY_MERGED') {
|
||
proto[name] = createMergedResultFunction(proto[name], property);
|
||
} else if (specPolicy === 'DEFINE_MANY') {
|
||
proto[name] = createChainedFunction(proto[name], property);
|
||
}
|
||
} else {
|
||
proto[name] = property;
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
// Add verbose displayName to the function, which helps when looking
|
||
// at profiling tools.
|
||
if (typeof property === 'function' && spec.displayName) {
|
||
proto[name].displayName = spec.displayName + '_' + name;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function mixStaticSpecIntoComponent(Constructor, statics) {
|
||
if (!statics) {
|
||
return;
|
||
}
|
||
|
||
for (var name in statics) {
|
||
var property = statics[name];
|
||
if (!statics.hasOwnProperty(name)) {
|
||
continue;
|
||
}
|
||
|
||
var isReserved = name in RESERVED_SPEC_KEYS;
|
||
_invariant(
|
||
!isReserved,
|
||
'ReactClass: You are attempting to define a reserved ' +
|
||
'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' +
|
||
'as an instance property instead; it will still be accessible on the ' +
|
||
'constructor.',
|
||
name
|
||
);
|
||
|
||
var isAlreadyDefined = name in Constructor;
|
||
if (isAlreadyDefined) {
|
||
var specPolicy = ReactClassStaticInterface.hasOwnProperty(name)
|
||
? ReactClassStaticInterface[name]
|
||
: null;
|
||
|
||
_invariant(
|
||
specPolicy === 'DEFINE_MANY_MERGED',
|
||
'ReactClass: You are attempting to define ' +
|
||
'`%s` on your component more than once. This conflict may be ' +
|
||
'due to a mixin.',
|
||
name
|
||
);
|
||
|
||
Constructor[name] = createMergedResultFunction(Constructor[name], property);
|
||
|
||
return;
|
||
}
|
||
|
||
Constructor[name] = property;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Merge two objects, but throw if both contain the same key.
|
||
*
|
||
* @param {object} one The first object, which is mutated.
|
||
* @param {object} two The second object
|
||
* @return {object} one after it has been mutated to contain everything in two.
|
||
*/
|
||
function mergeIntoWithNoDuplicateKeys(one, two) {
|
||
_invariant(
|
||
one && two && typeof one === 'object' && typeof two === 'object',
|
||
'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.'
|
||
);
|
||
|
||
for (var key in two) {
|
||
if (two.hasOwnProperty(key)) {
|
||
_invariant(
|
||
one[key] === undefined,
|
||
'mergeIntoWithNoDuplicateKeys(): ' +
|
||
'Tried to merge two objects with the same key: `%s`. This conflict ' +
|
||
'may be due to a mixin; in particular, this may be caused by two ' +
|
||
'getInitialState() or getDefaultProps() methods returning objects ' +
|
||
'with clashing keys.',
|
||
key
|
||
);
|
||
one[key] = two[key];
|
||
}
|
||
}
|
||
return one;
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes two functions and merges their return values.
|
||
*
|
||
* @param {function} one Function to invoke first.
|
||
* @param {function} two Function to invoke second.
|
||
* @return {function} Function that invokes the two argument functions.
|
||
* @private
|
||
*/
|
||
function createMergedResultFunction(one, two) {
|
||
return function mergedResult() {
|
||
var a = one.apply(this, arguments);
|
||
var b = two.apply(this, arguments);
|
||
if (a == null) {
|
||
return b;
|
||
} else if (b == null) {
|
||
return a;
|
||
}
|
||
var c = {};
|
||
mergeIntoWithNoDuplicateKeys(c, a);
|
||
mergeIntoWithNoDuplicateKeys(c, b);
|
||
return c;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Creates a function that invokes two functions and ignores their return vales.
|
||
*
|
||
* @param {function} one Function to invoke first.
|
||
* @param {function} two Function to invoke second.
|
||
* @return {function} Function that invokes the two argument functions.
|
||
* @private
|
||
*/
|
||
function createChainedFunction(one, two) {
|
||
return function chainedFunction() {
|
||
one.apply(this, arguments);
|
||
two.apply(this, arguments);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Binds a method to the component.
|
||
*
|
||
* @param {object} component Component whose method is going to be bound.
|
||
* @param {function} method Method to be bound.
|
||
* @return {function} The bound method.
|
||
*/
|
||
function bindAutoBindMethod(component, method) {
|
||
var boundMethod = method.bind(component);
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
boundMethod.__reactBoundContext = component;
|
||
boundMethod.__reactBoundMethod = method;
|
||
boundMethod.__reactBoundArguments = null;
|
||
var componentName = component.constructor.displayName;
|
||
var _bind = boundMethod.bind;
|
||
boundMethod.bind = function(newThis) {
|
||
for (
|
||
var _len = arguments.length,
|
||
args = Array(_len > 1 ? _len - 1 : 0),
|
||
_key = 1;
|
||
_key < _len;
|
||
_key++
|
||
) {
|
||
args[_key - 1] = arguments[_key];
|
||
}
|
||
|
||
// User is trying to bind() an autobound method; we effectively will
|
||
// ignore the value of "this" that the user is trying to use, so
|
||
// let's warn.
|
||
if (newThis !== component && newThis !== null) {
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
warning(
|
||
false,
|
||
'bind(): React component methods may only be bound to the ' +
|
||
'component instance. See %s',
|
||
componentName
|
||
);
|
||
}
|
||
} else if (!args.length) {
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
warning(
|
||
false,
|
||
'bind(): You are binding a component method to the component. ' +
|
||
'React does this for you automatically in a high-performance ' +
|
||
'way, so you can safely remove this call. See %s',
|
||
componentName
|
||
);
|
||
}
|
||
return boundMethod;
|
||
}
|
||
var reboundMethod = _bind.apply(boundMethod, arguments);
|
||
reboundMethod.__reactBoundContext = component;
|
||
reboundMethod.__reactBoundMethod = method;
|
||
reboundMethod.__reactBoundArguments = args;
|
||
return reboundMethod;
|
||
};
|
||
}
|
||
return boundMethod;
|
||
}
|
||
|
||
/**
|
||
* Binds all auto-bound methods in a component.
|
||
*
|
||
* @param {object} component Component whose method is going to be bound.
|
||
*/
|
||
function bindAutoBindMethods(component) {
|
||
var pairs = component.__reactAutoBindPairs;
|
||
for (var i = 0; i < pairs.length; i += 2) {
|
||
var autoBindKey = pairs[i];
|
||
var method = pairs[i + 1];
|
||
component[autoBindKey] = bindAutoBindMethod(component, method);
|
||
}
|
||
}
|
||
|
||
var IsMountedPreMixin = {
|
||
componentDidMount: function() {
|
||
this.__isMounted = true;
|
||
}
|
||
};
|
||
|
||
var IsMountedPostMixin = {
|
||
componentWillUnmount: function() {
|
||
this.__isMounted = false;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Add more to the ReactClass base class. These are all legacy features and
|
||
* therefore not already part of the modern ReactComponent.
|
||
*/
|
||
var ReactClassMixin = {
|
||
/**
|
||
* TODO: This will be deprecated because state should always keep a consistent
|
||
* type signature and the only use case for this, is to avoid that.
|
||
*/
|
||
replaceState: function(newState, callback) {
|
||
this.updater.enqueueReplaceState(this, newState, callback);
|
||
},
|
||
|
||
/**
|
||
* Checks whether or not this composite component is mounted.
|
||
* @return {boolean} True if mounted, false otherwise.
|
||
* @protected
|
||
* @final
|
||
*/
|
||
isMounted: function() {
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
warning(
|
||
this.__didWarnIsMounted,
|
||
'%s: isMounted is deprecated. Instead, make sure to clean up ' +
|
||
'subscriptions and pending requests in componentWillUnmount to ' +
|
||
'prevent memory leaks.',
|
||
(this.constructor && this.constructor.displayName) ||
|
||
this.name ||
|
||
'Component'
|
||
);
|
||
this.__didWarnIsMounted = true;
|
||
}
|
||
return !!this.__isMounted;
|
||
}
|
||
};
|
||
|
||
var ReactClassComponent = function() {};
|
||
_assign(
|
||
ReactClassComponent.prototype,
|
||
ReactComponent.prototype,
|
||
ReactClassMixin
|
||
);
|
||
|
||
/**
|
||
* Creates a composite component class given a class specification.
|
||
* See https://facebook.github.io/react/docs/top-level-api.html#react.createclass
|
||
*
|
||
* @param {object} spec Class specification (which must define `render`).
|
||
* @return {function} Component constructor function.
|
||
* @public
|
||
*/
|
||
function createClass(spec) {
|
||
// To keep our warnings more understandable, we'll use a little hack here to
|
||
// ensure that Constructor.name !== 'Constructor'. This makes sure we don't
|
||
// unnecessarily identify a class without displayName as 'Constructor'.
|
||
var Constructor = identity(function(props, context, updater) {
|
||
// This constructor gets overridden by mocks. The argument is used
|
||
// by mocks to assert on what gets mounted.
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
warning(
|
||
this instanceof Constructor,
|
||
'Something is calling a React component directly. Use a factory or ' +
|
||
'JSX instead. See: https://fb.me/react-legacyfactory'
|
||
);
|
||
}
|
||
|
||
// Wire up auto-binding
|
||
if (this.__reactAutoBindPairs.length) {
|
||
bindAutoBindMethods(this);
|
||
}
|
||
|
||
this.props = props;
|
||
this.context = context;
|
||
this.refs = emptyObject;
|
||
this.updater = updater || ReactNoopUpdateQueue;
|
||
|
||
this.state = null;
|
||
|
||
// ReactClasses doesn't have constructors. Instead, they use the
|
||
// getInitialState and componentWillMount methods for initialization.
|
||
|
||
var initialState = this.getInitialState ? this.getInitialState() : null;
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
// We allow auto-mocks to proceed as if they're returning null.
|
||
if (
|
||
initialState === undefined &&
|
||
this.getInitialState._isMockFunction
|
||
) {
|
||
// This is probably bad practice. Consider warning here and
|
||
// deprecating this convenience.
|
||
initialState = null;
|
||
}
|
||
}
|
||
_invariant(
|
||
typeof initialState === 'object' && !Array.isArray(initialState),
|
||
'%s.getInitialState(): must return an object or null',
|
||
Constructor.displayName || 'ReactCompositeComponent'
|
||
);
|
||
|
||
this.state = initialState;
|
||
});
|
||
Constructor.prototype = new ReactClassComponent();
|
||
Constructor.prototype.constructor = Constructor;
|
||
Constructor.prototype.__reactAutoBindPairs = [];
|
||
|
||
injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor));
|
||
|
||
mixSpecIntoComponent(Constructor, IsMountedPreMixin);
|
||
mixSpecIntoComponent(Constructor, spec);
|
||
mixSpecIntoComponent(Constructor, IsMountedPostMixin);
|
||
|
||
// Initialize the defaultProps property after all mixins have been merged.
|
||
if (Constructor.getDefaultProps) {
|
||
Constructor.defaultProps = Constructor.getDefaultProps();
|
||
}
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
// This is a tag to indicate that the use of these method names is ok,
|
||
// since it's used with createClass. If it's not, then it's likely a
|
||
// mistake so we'll warn you to use the static property, property
|
||
// initializer or constructor respectively.
|
||
if (Constructor.getDefaultProps) {
|
||
Constructor.getDefaultProps.isReactClassApproved = {};
|
||
}
|
||
if (Constructor.prototype.getInitialState) {
|
||
Constructor.prototype.getInitialState.isReactClassApproved = {};
|
||
}
|
||
}
|
||
|
||
_invariant(
|
||
Constructor.prototype.render,
|
||
'createClass(...): Class specification must implement a `render` method.'
|
||
);
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
warning(
|
||
!Constructor.prototype.componentShouldUpdate,
|
||
'%s has a method called ' +
|
||
'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
|
||
'The name is phrased as a question because the function is ' +
|
||
'expected to return a value.',
|
||
spec.displayName || 'A component'
|
||
);
|
||
warning(
|
||
!Constructor.prototype.componentWillRecieveProps,
|
||
'%s has a method called ' +
|
||
'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
|
||
spec.displayName || 'A component'
|
||
);
|
||
warning(
|
||
!Constructor.prototype.UNSAFE_componentWillRecieveProps,
|
||
'%s has a method called UNSAFE_componentWillRecieveProps(). ' +
|
||
'Did you mean UNSAFE_componentWillReceiveProps()?',
|
||
spec.displayName || 'A component'
|
||
);
|
||
}
|
||
|
||
// Reduce time spent doing lookups by setting these on the prototype.
|
||
for (var methodName in ReactClassInterface) {
|
||
if (!Constructor.prototype[methodName]) {
|
||
Constructor.prototype[methodName] = null;
|
||
}
|
||
}
|
||
|
||
return Constructor;
|
||
}
|
||
|
||
return createClass;
|
||
}
|
||
|
||
module.exports = factory;
|
||
|
||
|
||
/***/ }),
|
||
/* 4 */
|
||
/***/ (function(module, exports) {
|
||
|
||
/*
|
||
object-assign
|
||
(c) Sindre Sorhus
|
||
@license MIT
|
||
*/
|
||
|
||
'use strict';
|
||
/* eslint-disable no-unused-vars */
|
||
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
|
||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
|
||
|
||
function toObject(val) {
|
||
if (val === null || val === undefined) {
|
||
throw new TypeError('Object.assign cannot be called with null or undefined');
|
||
}
|
||
|
||
return Object(val);
|
||
}
|
||
|
||
function shouldUseNative() {
|
||
try {
|
||
if (!Object.assign) {
|
||
return false;
|
||
}
|
||
|
||
// Detect buggy property enumeration order in older V8 versions.
|
||
|
||
// https://bugs.chromium.org/p/v8/issues/detail?id=4118
|
||
var test1 = new String('abc'); // eslint-disable-line no-new-wrappers
|
||
test1[5] = 'de';
|
||
if (Object.getOwnPropertyNames(test1)[0] === '5') {
|
||
return false;
|
||
}
|
||
|
||
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
|
||
var test2 = {};
|
||
for (var i = 0; i < 10; i++) {
|
||
test2['_' + String.fromCharCode(i)] = i;
|
||
}
|
||
var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
|
||
return test2[n];
|
||
});
|
||
if (order2.join('') !== '0123456789') {
|
||
return false;
|
||
}
|
||
|
||
// https://bugs.chromium.org/p/v8/issues/detail?id=3056
|
||
var test3 = {};
|
||
'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
|
||
test3[letter] = letter;
|
||
});
|
||
if (Object.keys(Object.assign({}, test3)).join('') !==
|
||
'abcdefghijklmnopqrst') {
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
} catch (err) {
|
||
// We don't expect any of the above to throw, but better to be safe.
|
||
return false;
|
||
}
|
||
}
|
||
|
||
module.exports = shouldUseNative() ? Object.assign : function (target, source) {
|
||
var from;
|
||
var to = toObject(target);
|
||
var symbols;
|
||
|
||
for (var s = 1; s < arguments.length; s++) {
|
||
from = Object(arguments[s]);
|
||
|
||
for (var key in from) {
|
||
if (hasOwnProperty.call(from, key)) {
|
||
to[key] = from[key];
|
||
}
|
||
}
|
||
|
||
if (getOwnPropertySymbols) {
|
||
symbols = getOwnPropertySymbols(from);
|
||
for (var i = 0; i < symbols.length; i++) {
|
||
if (propIsEnumerable.call(from, symbols[i])) {
|
||
to[symbols[i]] = from[symbols[i]];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return to;
|
||
};
|
||
|
||
|
||
/***/ }),
|
||
/* 5 */
|
||
/***/ (function(module, exports) {
|
||
|
||
/**
|
||
* Copyright (c) 2013-present, Facebook, Inc.
|
||
*
|
||
* This source code is licensed under the MIT license found in the
|
||
* LICENSE file in the root directory of this source tree.
|
||
*
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
var emptyObject = {};
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
Object.freeze(emptyObject);
|
||
}
|
||
|
||
module.exports = emptyObject;
|
||
|
||
/***/ }),
|
||
/* 6 */
|
||
/***/ (function(module, exports) {
|
||
|
||
/**
|
||
* Copyright (c) 2013-present, Facebook, Inc.
|
||
*
|
||
* This source code is licensed under the MIT license found in the
|
||
* LICENSE file in the root directory of this source tree.
|
||
*
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
/**
|
||
* Use invariant() to assert state which your program assumes to be true.
|
||
*
|
||
* Provide sprintf-style format (only %s is supported) and arguments
|
||
* to provide information about what broke and what you were
|
||
* expecting.
|
||
*
|
||
* The invariant message will be stripped in production, but the invariant
|
||
* will remain to ensure logic does not differ in production.
|
||
*/
|
||
|
||
var validateFormat = function validateFormat(format) {};
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
validateFormat = function validateFormat(format) {
|
||
if (format === undefined) {
|
||
throw new Error('invariant requires an error message argument');
|
||
}
|
||
};
|
||
}
|
||
|
||
function invariant(condition, format, a, b, c, d, e, f) {
|
||
validateFormat(format);
|
||
|
||
if (!condition) {
|
||
var error;
|
||
if (format === undefined) {
|
||
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
|
||
} else {
|
||
var args = [a, b, c, d, e, f];
|
||
var argIndex = 0;
|
||
error = new Error(format.replace(/%s/g, function () {
|
||
return args[argIndex++];
|
||
}));
|
||
error.name = 'Invariant Violation';
|
||
}
|
||
|
||
error.framesToPop = 1; // we don't care about invariant's own frame
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
module.exports = invariant;
|
||
|
||
/***/ }),
|
||
/* 7 */
|
||
/***/ (function(module, exports, __webpack_require__) {
|
||
|
||
/**
|
||
* Copyright (c) 2014-present, Facebook, Inc.
|
||
*
|
||
* This source code is licensed under the MIT license found in the
|
||
* LICENSE file in the root directory of this source tree.
|
||
*
|
||
*/
|
||
|
||
'use strict';
|
||
|
||
var emptyFunction = __webpack_require__(8);
|
||
|
||
/**
|
||
* Similar to invariant but only logs a warning if the condition is not met.
|
||
* This can be used to log issues in development environments in critical
|
||
* paths. Removing the logging code for production environments will keep the
|
||
* same logic and follow the same code paths.
|
||
*/
|
||
|
||
var warning = emptyFunction;
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
var printWarning = function printWarning(format) {
|
||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||
args[_key - 1] = arguments[_key];
|
||
}
|
||
|
||
var argIndex = 0;
|
||
var message = 'Warning: ' + format.replace(/%s/g, function () {
|
||
return args[argIndex++];
|
||
});
|
||
if (typeof console !== 'undefined') {
|
||
console.error(message);
|
||
}
|
||
try {
|
||
// --- Welcome to debugging React ---
|
||
// This error was thrown as a convenience so that you can use this stack
|
||
// to find the callsite that caused this warning to fire.
|
||
throw new Error(message);
|
||
} catch (x) {}
|
||
};
|
||
|
||
warning = function warning(condition, format) {
|
||
if (format === undefined) {
|
||
throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
|
||
}
|
||
|
||
if (format.indexOf('Failed Composite propType: ') === 0) {
|
||
return; // Ignore CompositeComponent proptype check.
|
||
}
|
||
|
||
if (!condition) {
|
||
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
|
||
args[_key2 - 2] = arguments[_key2];
|
||
}
|
||
|
||
printWarning.apply(undefined, [format].concat(args));
|
||
}
|
||
};
|
||
}
|
||
|
||
module.exports = warning;
|
||
|
||
/***/ }),
|
||
/* 8 */
|
||
/***/ (function(module, exports) {
|
||
|
||
"use strict";
|
||
|
||
/**
|
||
* Copyright (c) 2013-present, Facebook, Inc.
|
||
*
|
||
* This source code is licensed under the MIT license found in the
|
||
* LICENSE file in the root directory of this source tree.
|
||
*
|
||
*
|
||
*/
|
||
|
||
function makeEmptyFunction(arg) {
|
||
return function () {
|
||
return arg;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* This function accepts and discards inputs; it has no side effects. This is
|
||
* primarily useful idiomatically for overridable function endpoints which
|
||
* always need to be callable, since JS lacks a null-call idiom ala Cocoa.
|
||
*/
|
||
var emptyFunction = function emptyFunction() {};
|
||
|
||
emptyFunction.thatReturns = makeEmptyFunction;
|
||
emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
|
||
emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
|
||
emptyFunction.thatReturnsNull = makeEmptyFunction(null);
|
||
emptyFunction.thatReturnsThis = function () {
|
||
return this;
|
||
};
|
||
emptyFunction.thatReturnsArgument = function (arg) {
|
||
return arg;
|
||
};
|
||
|
||
module.exports = emptyFunction;
|
||
|
||
/***/ }),
|
||
/* 9 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
var NumeralFormatter = function NumeralFormatter(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 getRawValue(value) {
|
||
return value.replace(this.delimiterRE, '').replace(this.numeralDecimalMark, '.');
|
||
},
|
||
|
||
format: function format(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;
|
||
|
||
/***/ }),
|
||
/* 10 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
var DateFormatter = function DateFormatter(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 initBlocks() {
|
||
var owner = this;
|
||
owner.datePattern.forEach(function (value) {
|
||
if (value === 'Y') {
|
||
owner.blocks.push(4);
|
||
} else {
|
||
owner.blocks.push(2);
|
||
}
|
||
});
|
||
},
|
||
|
||
getISOFormatDate: function getISOFormatDate() {
|
||
var owner = this,
|
||
date = owner.date;
|
||
|
||
return date[2] ? date[2] + '-' + owner.addLeadingZero(date[1]) + '-' + owner.addLeadingZero(date[0]) : '';
|
||
},
|
||
|
||
getBlocks: function getBlocks() {
|
||
return this.blocks;
|
||
},
|
||
|
||
getValidatedDate: function getValidatedDate(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 getFixedDateString(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 getRangeFixedDate(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 getFixedDate(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 isLeapYear(year) {
|
||
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
|
||
},
|
||
|
||
addLeadingZero: function addLeadingZero(number) {
|
||
return (number < 10 ? '0' : '') + number;
|
||
},
|
||
|
||
addLeadingZeroForYear: function addLeadingZeroForYear(number, fullYearMode) {
|
||
if (fullYearMode) {
|
||
return (number < 10 ? '000' : number < 100 ? '00' : number < 1000 ? '0' : '') + number;
|
||
}
|
||
|
||
return (number < 10 ? '0' : '') + number;
|
||
}
|
||
};
|
||
|
||
module.exports = DateFormatter;
|
||
|
||
/***/ }),
|
||
/* 11 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
var TimeFormatter = function TimeFormatter(timePattern, timeFormat) {
|
||
var owner = this;
|
||
|
||
owner.time = [];
|
||
owner.blocks = [];
|
||
owner.timePattern = timePattern;
|
||
owner.timeFormat = timeFormat;
|
||
owner.initBlocks();
|
||
};
|
||
|
||
TimeFormatter.prototype = {
|
||
initBlocks: function initBlocks() {
|
||
var owner = this;
|
||
owner.timePattern.forEach(function () {
|
||
owner.blocks.push(2);
|
||
});
|
||
},
|
||
|
||
getISOFormatTime: function getISOFormatTime() {
|
||
var owner = this,
|
||
time = owner.time;
|
||
|
||
return time[2] ? owner.addLeadingZero(time[0]) + ':' + owner.addLeadingZero(time[1]) + ':' + owner.addLeadingZero(time[2]) : '';
|
||
},
|
||
|
||
getBlocks: function getBlocks() {
|
||
return this.blocks;
|
||
},
|
||
|
||
getTimeFormatOptions: function getTimeFormatOptions() {
|
||
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 getValidatedTime(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 getFixedTimeString(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 getFixedTime(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 addLeadingZero(number) {
|
||
return (number < 10 ? '0' : '') + number;
|
||
}
|
||
};
|
||
|
||
module.exports = TimeFormatter;
|
||
|
||
/***/ }),
|
||
/* 12 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
var PhoneFormatter = function PhoneFormatter(formatter, delimiter) {
|
||
var owner = this;
|
||
|
||
owner.delimiter = delimiter || delimiter === '' ? delimiter : ' ';
|
||
owner.delimiterRE = delimiter ? new RegExp('\\' + delimiter, 'g') : '';
|
||
|
||
owner.formatter = formatter;
|
||
};
|
||
|
||
PhoneFormatter.prototype = {
|
||
setFormatter: function setFormatter(formatter) {
|
||
this.formatter = formatter;
|
||
},
|
||
|
||
format: function format(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;
|
||
|
||
/***/ }),
|
||
/* 13 */
|
||
/***/ (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 getStrictBlocks(block) {
|
||
var total = block.reduce(function (prev, current) {
|
||
return prev + current;
|
||
}, 0);
|
||
|
||
return block.concat(19 - total);
|
||
},
|
||
|
||
getInfo: function getInfo(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;
|
||
|
||
/***/ }),
|
||
/* 14 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
var Util = {
|
||
noop: function noop() {},
|
||
|
||
strip: function strip(value, re) {
|
||
return value.replace(re, '');
|
||
},
|
||
|
||
getPostDelimiter: function getPostDelimiter(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 getDelimiterREByDelimiter(delimiter) {
|
||
return new RegExp(delimiter.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1'), 'g');
|
||
},
|
||
|
||
getNextCursorPosition: function getNextCursorPosition(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 getPositionOffset(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 stripDelimiters(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 headStr(str, length) {
|
||
return str.slice(0, length);
|
||
},
|
||
|
||
getMaxLength: function getMaxLength(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 getPrefixStrippedValue(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 getFirstDiffIndex(prev, current) {
|
||
var index = 0;
|
||
|
||
while (prev.charAt(index) === current.charAt(index)) {
|
||
if (prev.charAt(index++) === '') {
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
return index;
|
||
},
|
||
|
||
getFormattedValue: function getFormattedValue(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 fixPrefixCursor(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 checkFullSelection(value) {
|
||
try {
|
||
var selection = window.getSelection() || document.getSelection() || {};
|
||
return selection.toString().length === value.length;
|
||
} catch (ex) {
|
||
// Ignore
|
||
}
|
||
|
||
return false;
|
||
},
|
||
|
||
setSelection: function setSelection(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 getActiveElement(parent) {
|
||
var activeElement = parent.activeElement;
|
||
if (activeElement && activeElement.shadowRoot) {
|
||
return this.getActiveElement(activeElement.shadowRoot);
|
||
}
|
||
return activeElement;
|
||
},
|
||
|
||
isAndroid: function isAndroid() {
|
||
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 isAndroidBackspaceKeydown(lastInputValue, currentInputValue) {
|
||
if (!this.isAndroid() || !lastInputValue || !currentInputValue) {
|
||
return false;
|
||
}
|
||
|
||
return currentInputValue === lastInputValue.slice(0, -1);
|
||
}
|
||
};
|
||
|
||
module.exports = Util;
|
||
|
||
/***/ }),
|
||
/* 15 */
|
||
/***/ (function(module, exports) {
|
||
|
||
'use strict';
|
||
|
||
/**
|
||
* Props Assignment
|
||
*
|
||
* Separate this, so react module can share the usage
|
||
*/
|
||
|
||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||
|
||
var DefaultProperties = {
|
||
// Maybe change to object-assign
|
||
// for now just keep it as simple
|
||
assign: function assign(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 === 'undefined' ? 'undefined' : _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;
|
||
|
||
/***/ })
|
||
/******/ ])
|
||
});
|
||
; |