1(function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 typeof define === 'function' && define.amd ? define(factory) : 4 (global.IMask = factory()); 5}(this, (function () { 'use strict'; 6 7// 7.2.1 RequireObjectCoercible(argument) 8var _defined = function (it) { 9 if (it == undefined) throw TypeError("Can't call method on " + it); 10 return it; 11}; 12 13// 7.1.13 ToObject(argument) 14 15var _toObject = function (it) { 16 return Object(_defined(it)); 17}; 18 19var hasOwnProperty = {}.hasOwnProperty; 20var _has = function (it, key) { 21 return hasOwnProperty.call(it, key); 22}; 23 24var toString = {}.toString; 25 26var _cof = function (it) { 27 return toString.call(it).slice(8, -1); 28}; 29 30// fallback for non-array-like ES3 and non-enumerable old V8 strings 31 32// eslint-disable-next-line no-prototype-builtins 33var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) { 34 return _cof(it) == 'String' ? it.split('') : Object(it); 35}; 36 37// to indexed object, toObject with fallback for non-array-like ES3 strings 38 39 40var _toIobject = function (it) { 41 return _iobject(_defined(it)); 42}; 43 44// 7.1.4 ToInteger 45var ceil = Math.ceil; 46var floor = Math.floor; 47var _toInteger = function (it) { 48 return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); 49}; 50 51// 7.1.15 ToLength 52 53var min = Math.min; 54var _toLength = function (it) { 55 return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 56}; 57 58var max = Math.max; 59var min$1 = Math.min; 60var _toAbsoluteIndex = function (index, length) { 61 index = _toInteger(index); 62 return index < 0 ? max(index + length, 0) : min$1(index, length); 63}; 64 65// false -> Array#indexOf 66// true -> Array#includes 67 68 69 70var _arrayIncludes = function (IS_INCLUDES) { 71 return function ($this, el, fromIndex) { 72 var O = _toIobject($this); 73 var length = _toLength(O.length); 74 var index = _toAbsoluteIndex(fromIndex, length); 75 var value; 76 // Array#includes uses SameValueZero equality algorithm 77 // eslint-disable-next-line no-self-compare 78 if (IS_INCLUDES && el != el) while (length > index) { 79 value = O[index++]; 80 // eslint-disable-next-line no-self-compare 81 if (value != value) return true; 82 // Array#indexOf ignores holes, Array#includes - not 83 } else for (;length > index; index++) if (IS_INCLUDES || index in O) { 84 if (O[index] === el) return IS_INCLUDES || index || 0; 85 } return !IS_INCLUDES && -1; 86 }; 87}; 88 89function createCommonjsModule(fn, module) { 90 return module = { exports: {} }, fn(module, module.exports), module.exports; 91} 92 93var _global = createCommonjsModule(function (module) { 94// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 95var global = module.exports = typeof window != 'undefined' && window.Math == Math 96 ? window : typeof self != 'undefined' && self.Math == Math ? self 97 // eslint-disable-next-line no-new-func 98 : Function('return this')(); 99if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef 100}); 101 102var SHARED = '__core-js_shared__'; 103var store = _global[SHARED] || (_global[SHARED] = {}); 104var _shared = function (key) { 105 return store[key] || (store[key] = {}); 106}; 107 108var id = 0; 109var px = Math.random(); 110var _uid = function (key) { 111 return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); 112}; 113 114var shared = _shared('keys'); 115 116var _sharedKey = function (key) {
vendor: 4,522 bytes, lines 117-271
117 return shared[key] || (shared[key] = _uid(key)); 118}; 119 120var arrayIndexOf = _arrayIncludes(false); 121var IE_PROTO = _sharedKey('IE_PROTO'); 122 123var _objectKeysInternal = function (object, names) { 124 var O = _toIobject(object); 125 var i = 0; 126 var result = []; 127 var key; 128 for (key in O) if (key != IE_PROTO) _has(O, key) && result.push(key); 129 // Don't enum bug & hidden keys 130 while (names.length > i) if (_has(O, key = names[i++])) { 131 ~arrayIndexOf(result, key) || result.push(key); 132 } 133 return result; 134}; 135 136// IE 8- don't enum bug keys 137var _enumBugKeys = ( 138 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' 139).split(','); 140 141// 19.1.2.14 / 15.2.3.14 Object.keys(O) 142 143 144 145var _objectKeys = Object.keys || function keys(O) { 146 return _objectKeysInternal(O, _enumBugKeys); 147}; 148 149var _core = createCommonjsModule(function (module) { 150var core = module.exports = { version: '2.5.3' }; 151if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef 152}); 153 154var _core_1 = _core.version; 155 156var _isObject = function (it) { 157 return typeof it === 'object' ? it !== null : typeof it === 'function'; 158}; 159 160var _anObject = function (it) { 161 if (!_isObject(it)) throw TypeError(it + ' is not an object!'); 162 return it; 163}; 164 165var _fails = function (exec) { 166 try { 167 return !!exec(); 168 } catch (e) { 169 return true; 170 } 171}; 172 173// Thank's IE8 for his funny defineProperty 174var _descriptors = !_fails(function () { 175 return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; 176}); 177 178var document$1 = _global.document; 179// typeof document.createElement is 'object' in old IE 180var is = _isObject(document$1) && _isObject(document$1.createElement); 181var _domCreate = function (it) { 182 return is ? document$1.createElement(it) : {}; 183}; 184 185var _ie8DomDefine = !_descriptors && !_fails(function () { 186 return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7; 187}); 188 189// 7.1.1 ToPrimitive(input [, PreferredType]) 190 191// instead of the ES6 spec version, we didn't implement @@toPrimitive case 192// and the second argument - flag - preferred type is a string 193var _toPrimitive = function (it, S) { 194 if (!_isObject(it)) return it; 195 var fn, val; 196 if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val; 197 if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val; 198 if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val; 199 throw TypeError("Can't convert object to primitive value"); 200}; 201 202var dP = Object.defineProperty; 203 204var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) { 205 _anObject(O); 206 P = _toPrimitive(P, true); 207 _anObject(Attributes); 208 if (_ie8DomDefine) try { 209 return dP(O, P, Attributes); 210 } catch (e) { /* empty */ } 211 if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); 212 if ('value' in Attributes) O[P] = Attributes.value; 213 return O; 214}; 215 216var _objectDp = { 217 f: f 218}; 219 220var _propertyDesc = function (bitmap, value) { 221 return { 222 enumerable: !(bitmap & 1), 223 configurable: !(bitmap & 2), 224 writable: !(bitmap & 4), 225 value: value 226 }; 227}; 228 229var _hide = _descriptors ? function (object, key, value) { 230 return _objectDp.f(object, key, _propertyDesc(1, value)); 231} : function (object, key, value) { 232 object[key] = value; 233 return object; 234}; 235 236var _redefine = createCommonjsModule(function (module) { 237var SRC = _uid('src'); 238var TO_STRING = 'toString'; 239var $toString = Function[TO_STRING]; 240var TPL = ('' + $toString).split(TO_STRING); 241 242_core.inspectSource = function (it) { 243 return $toString.call(it); 244}; 245 246(module.exports = function (O, key, val, safe) { 247 var isFunction = typeof val == 'function'; 248 if (isFunction) _has(val, 'name') || _hide(val, 'name', key); 249 if (O[key] === val) return; 250 if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); 251 if (O === _global) { 252 O[key] = val; 253 } else if (!safe) { 254 delete O[key]; 255 _hide(O, key, val); 256 } else if (O[key]) { 257 O[key] = val; 258 } else { 259 _hide(O, key, val); 260 } 261// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative 262})(Function.prototype, TO_STRING, function toString() { 263 return typeof this == 'function' && this[SRC] || $toString.call(this); 264}); 265}); 266 267var _aFunction = function (it) { 268 if (typeof it != 'function') throw TypeError(it + ' is not a function!'); 269 return it; 270}; 271
272// optional / simple context binding 273 274var _ctx = function (fn, that, length) { 275 _aFunction(fn); 276 if (that === undefined) return fn; 277 switch (length) { 278 case 1: return function (a) { 279 return fn.call(that, a); 280 }; 281 case 2: return function (a, b) { 282 return fn.call(that, a, b); 283 }; 284 case 3: return function (a, b, c) { 285 return fn.call(that, a, b, c); 286 }; 287 } 288 return function (/* ...args */) { 289 return fn.apply(that, arguments); 290 }; 291}; 292 293var PROTOTYPE = 'prototype'; 294 295var $export = function (type, name, source) { 296 var IS_FORCED = type & $export.F; 297 var IS_GLOBAL = type & $export.G; 298 var IS_STATIC = type & $export.S; 299 var IS_PROTO = type & $export.P; 300 var IS_BIND = type & $export.B; 301 var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE]; 302 var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {}); 303 var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}); 304 var key, own, out, exp; 305 if (IS_GLOBAL) source = name; 306 for (key in source) { 307 // contains in native 308 own = !IS_FORCED && target && target[key] !== undefined; 309 // export native or passed 310 out = (own ? target : source)[key]; 311 // bind timers to global for call from export context 312 exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out; 313 // extend global 314 if (target) _redefine(target, key, out, type & $export.U); 315 // export 316 if (exports[key] != out) _hide(exports, key, exp); 317 if (IS_PROTO && expProto[key] != out) expProto[key] = out; 318 } 319}; 320_global.core = _core; 321// type bitmap 322$export.F = 1; // forced 323$export.G = 2; // global 324$export.S = 4; // static 325$export.P = 8; // proto 326$export.B = 16; // bind 327$export.W = 32; // wrap 328$export.U = 64; // safe 329$export.R = 128; // real proto method for `library` 330var _export = $export; 331 332// most Object methods by ES6 should accept primitives 333 334 335 336var _objectSap = function (KEY, exec) { 337 var fn = (_core.Object || {})[KEY] || Object[KEY]; 338 var exp = {}; 339 exp[KEY] = exec(fn); 340 _export(_export.S + _export.F * _fails(function () { fn(1); }), 'Object', exp); 341}; 342 343// 19.1.2.14 Object.keys(O) 344 345 346 347_objectSap('keys', function () { 348 return function keys(it) { 349 return _objectKeys(_toObject(it)); 350 }; 351}); 352 353var keys = _core.Object.keys; 354 355var _stringRepeat = function repeat(count) { 356 var str = String(_defined(this)); 357 var res = ''; 358 var n = _toInteger(count); 359 if (n < 0 || n == Infinity) throw RangeError("Count can't be negative"); 360 for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str; 361 return res; 362}; 363 364_export(_export.P, 'String', { 365 // 21.1.3.13 String.prototype.repeat(count) 366 repeat: _stringRepeat 367}); 368 369var repeat$1 = _core.String.repeat; 370 371// https://github.com/tc39/proposal-string-pad-start-end 372 373 374 375 376var _stringPad = function (that, maxLength, fillString, left) { 377 var S = String(_defined(that)); 378 var stringLength = S.length; 379 var fillStr = fillString === undefined ? ' ' : String(fillString); 380 var intMaxLength = _toLength(maxLength); 381 if (intMaxLength <= stringLength || fillStr == '') return S; 382 var fillLen = intMaxLength - stringLength; 383 var stringFiller = _stringRepeat.call(fillStr, Math.ceil(fillLen / fillStr.length)); 384 if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen); 385 return left ? stringFiller + S : S + stringFiller; 386}; 387 388var navigator = _global.navigator; 389 390var _userAgent = navigator && navigator.userAgent || ''; 391 392// https://github.com/tc39/proposal-string-pad-start-end 393 394 395 396 397// https://github.com/zloirock/core-js/issues/280 398_export(_export.P + _export.F * /Version\/10\.\d+(\.\d+)? Safari\//.test(_userAgent), 'String', { 399 padStart: function padStart(maxLength /* , fillString = ' ' */) { 400 return _stringPad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true); 401 } 402}); 403 404var padStart = _core.String.padStart; 405 406// https://github.com/tc39/proposal-string-pad-start-end 407 408 409 410 411// https://github.com/zloirock/core-js/issues/280 412_export(_export.P + _export.F * /Version\/10\.\d+(\.\d+)? Safari\//.test(_userAgent), 'String', { 413 padEnd: function padEnd(maxLength /* , fillString = ' ' */) { 414 return _stringPad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false); 415 } 416}); 417 418var padEnd = _core.String.padEnd; 419 420var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 421 return typeof obj; 422} : function (obj) { 423 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 424}; 425 426 427 428 429 430 431 432 433 434 435 436var classCallCheck = function (instance, Constructor) { 437 if (!(instance instanceof Constructor)) { 438 throw new TypeError("Cannot call a class as a function"); 439 } 440}; 441 442var createClass = function () { 443 function defineProperties(target, props) { 444 for (var i = 0; i < props.length; i++) { 445 var descriptor = props[i]; 446 descriptor.enumerable = descriptor.enumerable || false; 447 descriptor.configurable = true; 448 if ("value" in descriptor) descriptor.writable = true; 449 Object.defineProperty(target, descriptor.key, descriptor); 450 } 451 } 452 453 return function (Constructor, protoProps, staticProps) { 454 if (protoProps) defineProperties(Constructor.prototype, protoProps); 455 if (staticProps) defineProperties(Constructor, staticProps); 456 return Constructor; 457 }; 458}(); 459 460 461 462 463 464 465 466var _extends = Object.assign || function (target) { 467 for (var i = 1; i < arguments.length; i++) { 468 var source = arguments[i]; 469 470 for (var key in source) { 471 if (Object.prototype.hasOwnProperty.call(source, key)) { 472 target[key] = source[key]; 473 } 474 } 475 } 476 477 return target; 478}; 479 480var get = function get(object, property, receiver) { 481 if (object === null) object = Function.prototype; 482 var desc = Object.getOwnPropertyDescriptor(object, property); 483 484 if (desc === undefined) { 485 var parent = Object.getPrototypeOf(object); 486 487 if (parent === null) { 488 return undefined; 489 } else { 490 return get(parent, property, receiver); 491 } 492 } else if ("value" in desc) { 493 return desc.value; 494 } else { 495 var getter = desc.get; 496 497 if (getter === undefined) { 498 return undefined; 499 } 500 501 return getter.call(receiver); 502 } 503}; 504 505var inherits = function (subClass, superClass) { 506 if (typeof superClass !== "function" && superClass !== null) { 507 throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); 508 } 509 510 subClass.prototype = Object.create(superClass && superClass.prototype, { 511 constructor: { 512 value: subClass, 513 enumerable: false, 514 writable: true, 515 configurable: true 516 } 517 }); 518 if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 519}; 520 521 522 523 524 525 526 527 528 529 530 531var possibleConstructorReturn = function (self, call) { 532 if (!self) { 533 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 534 } 535 536 return call && (typeof call === "object" || typeof call === "function") ? call : self; 537}; 538 539 540 541var set = function set(object, property, value, receiver) { 542 var desc = Object.getOwnPropertyDescriptor(object, property); 543 544 if (desc === undefined) { 545 var parent = Object.getPrototypeOf(object); 546 547 if (parent !== null) { 548 set(parent, property, value, receiver); 549 } 550 } else if ("value" in desc && desc.writable) { 551 desc.value = value; 552 } else { 553 var setter = desc.set; 554 555 if (setter !== undefined) { 556 setter.call(receiver, value); 557 } 558 } 559 560 return value; 561}; 562 563var slicedToArray = function () { 564 function sliceIterator(arr, i) { 565 var _arr = []; 566 var _n = true; 567 var _d = false;
568 var _e = undefined; 569 570 try { 571 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { 572 _arr.push(_s.value); 573 574 if (i && _arr.length === i) break; 575 } 576 } catch (err) { 577 _d = true; 578 _e = err; 579 } finally { 580 try { 581 if (!_n && _i["return"]) _i["return"](); 582 } finally { 583 if (_d) throw _e; 584 } 585 } 586 587 return _arr; 588 } 589 590 return function (arr, i) { 591 if (Array.isArray(arr)) { 592 return arr; 593 } else if (Symbol.iterator in Object(arr)) { 594 return sliceIterator(arr, i); 595 } else { 596 throw new TypeError("Invalid attempt to destructure non-iterable instance"); 597 } 598 }; 599}(); 600 601 602 603 604 605 606 607 608 609 610 611 612 613var toConsumableArray = function (arr) { 614 if (Array.isArray(arr)) { 615 for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; 616 617 return arr2; 618 } else { 619 return Array.from(arr); 620 } 621}; 622 623/** Checks if value is string */ 624function isString(str) { 625 return typeof str === 'string' || str instanceof String; 626} 627 628/** Conforms string with fallback */ 629function conform(res, str) { 630 var fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; 631 632 return isString(res) ? res : res ? str : fallback; 633} 634 635/** 636 Direction 637 @prop {number} NONE 638 @prop {number} LEFT 639 @prop {number} RIGHT 640*/ 641var DIRECTION = { 642 NONE: 0, 643 LEFT: -1, 644 RIGHT: 1 645 /** 646 Direction 647 @enum {number} 648 */ 649}; 650 651/** Returns next char position in direction */ 652function indexInDirection(pos, direction) { 653 if (direction === DIRECTION.LEFT) --pos; 654 return pos; 655} 656 657/** Escapes regular expression control chars */ 658function escapeRegExp(str) { 659 return str.replace(/([.*+?^=!:${}()|[\]/\\])/g, '\\$1'); 660} 661 662// cloned from https://github.com/epoberezkin/fast-deep-equal with small changes 663function objectIncludes(b, a) { 664 if (a === b) return true; 665 666 var arrA = Array.isArray(a), 667 arrB = Array.isArray(b), 668 i; 669 670 if (arrA && arrB) { 671 if (a.length != b.length) return false; 672 for (i = 0; i < a.length; i++) { 673 if (!objectIncludes(a[i], b[i])) return false; 674 }return true; 675 } 676 677 if (arrA != arrB) return false; 678 679 if (a && b && (typeof a === 'undefined' ? 'undefined' : _typeof(a)) === 'object' && (typeof b === 'undefined' ? 'undefined' : _typeof(b)) === 'object') { 680 var keys = Object.keys(a); 681 // if (keys.length !== Object.keys(b).length) return false; 682 683 var dateA = a instanceof Date, 684 dateB = b instanceof Date; 685 if (dateA && dateB) return a.getTime() == b.getTime(); 686 if (dateA != dateB) return false; 687 688 var regexpA = a instanceof RegExp, 689 regexpB = b instanceof RegExp; 690 if (regexpA && regexpB) return a.toString() == b.toString(); 691 if (regexpA != regexpB) return false; 692 693 for (i = 0; i < keys.length; i++) { 694 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 695 }for (i = 0; i < keys.length; i++) { 696 if (!objectIncludes(a[keys[i]], b[keys[i]])) return false; 697 }return true; 698 } 699 700 return false; 701} 702 703/* eslint-disable no-undef */ 704var g = typeof window !== 'undefined' && window || typeof global !== 'undefined' && global.global === global && global || typeof self !== 'undefined' && self.self === self && self || {}; 705/* eslint-enable no-undef */ 706 707/** Selection range */ 708 709/** Provides details of changing input */ 710 711var ActionDetails = function () { 712 /** Old input value */ 713 714 /** Current input value */ 715 function ActionDetails(value, cursorPos, oldValue, oldSelection) { 716 classCallCheck(this, ActionDetails); 717 718 this.value = value;
719 this.cursorPos = cursorPos; 720 this.oldValue = oldValue; 721 this.oldSelection = oldSelection; 722 723 // double check if left part was changed (autofilling, other non-standard input triggers) 724 while (this.value.slice(0, this.startChangePos) !== this.oldValue.slice(0, this.startChangePos)) { 725 --this.oldSelection.start; 726 } 727 } 728 729 /** 730 Start changing position 731 @readonly 732 */ 733 734 /** Old selection */ 735 736 /** Current cursor position */ 737 738 739 createClass(ActionDetails, [{ 740 key: 'startChangePos', 741 get: function get$$1() { 742 return Math.min(this.cursorPos, this.oldSelection.start); 743 } 744 745 /** 746 Inserted symbols count 747 @readonly 748 */ 749 750 }, { 751 key: 'insertedCount', 752 get: function get$$1() { 753 return this.cursorPos - this.startChangePos; 754 } 755 756 /** 757 Inserted symbols 758 @readonly 759 */ 760 761 }, { 762 key: 'inserted', 763 get: function get$$1() { 764 return this.value.substr(this.startChangePos, this.insertedCount); 765 } 766 767 /** 768 Removed symbols count 769 @readonly 770 */ 771 772 }, { 773 key: 'removedCount', 774 get: function get$$1() { 775 // Math.max for opposite operation 776 return Math.max(this.oldSelection.end - this.startChangePos || 777 // for Delete 778 this.oldValue.length - this.value.length, 0); 779 } 780 781 /** 782 Removed symbols 783 @readonly 784 */ 785 786 }, { 787 key: 'removed', 788 get: function get$$1() { 789 return this.oldValue.substr(this.startChangePos, this.removedCount); 790 } 791 792 /** 793 Unchanged head symbols 794 @readonly 795 */ 796 797 }, { 798 key: 'head', 799 get: function get$$1() { 800 return this.value.substring(0, this.startChangePos); 801 } 802 803 /** 804 Unchanged tail symbols 805 @readonly 806 */ 807 808 }, { 809 key: 'tail', 810 get: function get$$1() { 811 return this.value.substring(this.startChangePos + this.insertedCount); 812 } 813 814 /** 815 Remove direction 816 @readonly 817 */ 818 819 }, { 820 key: 'removeDirection', 821 get: function get$$1() { 822 if (!this.removedCount || this.insertedCount) return DIRECTION.NONE; 823 824 // align right if delete at right or if range removed (event with backspace) 825 return this.oldSelection.end === this.cursorPos || this.oldSelection.start === this.cursorPos ? DIRECTION.RIGHT : DIRECTION.LEFT; 826 } 827 }]); 828 return ActionDetails; 829}(); 830 831/** 832 Provides details of changing model value 833 @param {Object} [details] 834 @param {string} [details.inserted] - Inserted symbols 835 @param {boolean} [details.overflow] - Is overflowed 836 @param {number} [details.removeCount] - Removed symbols count 837 @param {number} [details.shift] - Additional offset if any changes occurred before current position 838*/ 839var ChangeDetails = function () { 840 /** Additional offset if any changes occurred before current position */ 841 842 /** Inserted symbols */ 843 function ChangeDetails(details) { 844 classCallCheck(this, ChangeDetails); 845 846 _extends(this, { 847 inserted: '', 848 overflow: false, 849 shift: 0 850 }, details); 851 } 852 853 /** 854 Aggregate changes 855 @returns {ChangeDetails} `this` 856 */ 857 858 /** Is overflowed */ 859 860 861 createClass(ChangeDetails, [{ 862 key: 'aggregate', 863 value: function aggregate(details) { 864 if (details.rawInserted) this.rawInserted += details.rawInserted; 865 this.inserted += details.inserted; 866 this.shift += details.shift; 867 this.overflow = this.overflow || details.overflow; 868 return this; 869 } 870 871 /** Total offset considering all changes */ 872 873 }, { 874 key: 'offset', 875 get: function get$$1() { 876 return this.shift + this.inserted.length; 877 } 878 879 /** Raw inserted is used by dynamic mask */ 880 881 }, { 882 key: 'rawInserted', 883 get: function get$$1() { 884 return this._rawInserted != null ? this._rawInserted : this.inserted; 885 }, 886 set: function set$$1(rawInserted) { 887 this._rawInserted = rawInserted; 888 } 889 }]); 890 return ChangeDetails; 891}(); 892 893/** Supported mask type */ 894 895 896/** Append flags */ 897 898 899/** Extract flags */ 900 901/** Provides common masking stuff */ 902var Masked = function () { 903 /** Does additional processing in the end of editing */ 904 905 /** Transforms value before mask processing */ 906 function Masked(opts) { 907 classCallCheck(this, Masked); 908 909 this._value = ''; 910 this._update(_extends({}, Masked.DEFAULTS, opts)); 911 this.isInitialized = true; 912 } 913 914 /** Sets and applies new options */ 915 916 /** */ 917 918 /** Validates if value is acceptable */ 919 // $Shape<MaskedOptions>; TODO after fix https://github.com/facebook/flow/issues/4773 920 921 /** @type {Mask} */ 922 923 924 createClass(Masked, [{ 925 key: 'updateOptions', 926 value: function updateOptions(opts) { 927 this.withValueRefresh(this._update.bind(this, opts)); 928 } 929 930 /** 931 Sets new options 932 @protected 933 */ 934 935 }, { 936 key: '_update', 937 value: function _update(opts) { 938 _extends(this, opts); 939 } 940 941 /** Clones masked with options and value */ 942 943 }, { 944 key: 'clone', 945 value: function clone() { 946 var m = new Masked(this); 947 m._value = this.value.slice(); 948 return m; 949 } 950 951 /** */ 952 953 }, { 954 key: 'assign', 955 value: function assign(source) { 956 // $FlowFixMe 957 return _extends(this, source); 958 } 959 960 /** Resets value */ 961 962 }, { 963 key: 'reset', 964 value: function reset() { 965 this._value = ''; 966 } 967 968 /** */ 969 970 }, { 971 key: 'resolve', 972 973 974 /** Resolve new value */ 975 value: function resolve(value) { 976 this.reset();
977 this._append(value, { input: true }); 978 this._appendTail(); 979 this.doCommit(); 980 return this.value; 981 } 982 983 /** */ 984 985 }, { 986 key: 'nearestInputPos', 987 988 989 /** Finds nearest input position in direction */ 990 value: function nearestInputPos(cursorPos, direction) { 991 return cursorPos; 992 } 993 994 /** Extracts value in range considering flags */ 995 996 }, { 997 key: 'extractInput', 998 value: function extractInput() { 999 var fromPos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 1000 var toPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length; 1001 return this.value.slice(fromPos, toPos); 1002 } 1003 1004 /** Extracts tail in range */ 1005 1006 }, { 1007 key: '_extractTail', 1008 value: function _extractTail() { 1009 var fromPos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 1010 var toPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length; 1011 1012 return { 1013 value: this.extractInput(fromPos, toPos), 1014 fromPos: fromPos, 1015 toPos: toPos 1016 }; 1017 } 1018 1019 /** Appends tail */ 1020 1021 }, { 1022 key: '_appendTail', 1023 value: function _appendTail(tail) { 1024 return this._append(tail ? tail.value : '', { tail: true }); 1025 } 1026 1027 /** Appends symbols considering flags */ 1028 1029 }, { 1030 key: '_append', 1031 value: function _append(str) { 1032 var flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1033 1034 var oldValueLength = this.value.length; 1035 var consistentValue = this.clone(); 1036 var overflow = false; 1037 1038 str = this.doPrepare(str, flags); 1039 1040 for (var ci = 0; ci < str.length; ++ci) { 1041 this._value += str[ci]; 1042 if (this.doValidate(flags) === false) { 1043 this.assign(consistentValue); 1044 if (!flags.input) { 1045 // in `input` mode dont skip invalid chars 1046 overflow = true; 1047 break; 1048 } 1049 } 1050 1051 consistentValue = this.clone(); 1052 } 1053 1054 return new ChangeDetails({ 1055 inserted: this.value.slice(oldValueLength), 1056 overflow: overflow 1057 }); 1058 } 1059 1060 /** Appends symbols considering tail */ 1061 1062 }, { 1063 key: 'appendWithTail', 1064 value: function appendWithTail(str, tail) { 1065 // TODO refactor 1066 var aggregateDetails = new ChangeDetails(); 1067 var consistentValue = this.clone(); 1068 var consistentAppended = void 0; 1069 1070 for (var ci = 0; ci < str.length; ++ci) { 1071 var ch = str[ci]; 1072 1073 var appendDetails = this._append(ch, { input: true }); 1074 consistentAppended = this.clone(); 1075 var tailAppended = !appendDetails.overflow && !this._appendTail(tail).overflow; 1076 if (!tailAppended || this.doValidate({ tail: true }) === false) { 1077 this.assign(consistentValue); 1078 break; 1079 } 1080 1081 this.assign(consistentAppended); 1082 consistentValue = this.clone(); 1083 aggregateDetails.aggregate(appendDetails); 1084 } 1085 1086 // TODO needed for cases when 1087 // 1) REMOVE ONLY AND NO LOOP AT ALL 1088 // 2) last loop iteration removes tail 1089 // 3) when breaks on tail insert 1090 1091 // aggregate only shift from tail 1092 aggregateDetails.shift += this._appendTail(tail).shift; 1093 1094 return aggregateDetails; 1095 } 1096 1097 /** */ 1098 1099 }, { 1100 key: 'remove', 1101 value: function remove() { 1102 var from = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 1103 var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length - from; 1104 1105 this._value = this.value.slice(0, from) + this.value.slice(from + count); 1106 return new ChangeDetails(); 1107 } 1108 1109 /** Calls function and reapplies current value */ 1110 1111 }, { 1112 key: 'withValueRefresh', 1113 value: function withValueRefresh(fn) { 1114 if (this._refreshing || !this.isInitialized) return fn(); 1115 this._refreshing = true; 1116 1117 var unmasked = this.unmaskedValue; 1118 1119 var ret = fn(); 1120 1121 this.unmaskedValue = unmasked; 1122 1123 delete this._refreshing; 1124 return ret; 1125 } 1126 1127 /** 1128 Prepares string before mask processing 1129 @protected 1130 */ 1131 1132 }, { 1133 key: 'doPrepare', 1134 value: function doPrepare(str) { 1135 var flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1136 1137 return this.prepare(str, this, flags); 1138 } 1139 1140 /** 1141 Validates if value is acceptable 1142 @protected 1143 */ 1144 1145 }, { 1146 key: 'doValidate', 1147 value: function doValidate(flags) { 1148 return this.validate(this.value, this, flags); 1149 } 1150 1151 /** 1152 Does additional processing in the end of editing 1153 @protected 1154 */ 1155 1156 }, { 1157 key: 'doCommit', 1158 value: function doCommit() { 1159 this.commit(this.value, this); 1160 } 1161 1162 // TODO 1163 // insert (str, fromPos, flags) 1164 1165 /** */ 1166 1167 }, { 1168 key: 'splice', 1169 value: function splice(start, deleteCount, inserted, removeDirection) { 1170 var tailPos = start + deleteCount; 1171 var tail = this._extractTail(tailPos); 1172 1173 var startChangePos = this.nearestInputPos(start, removeDirection); 1174 var changeDetails = new ChangeDetails({ 1175 shift: startChangePos - start // adjust shift if start was aligned 1176 }).aggregate(this.remove(startChangePos)).aggregate(this.appendWithTail(inserted, tail)); 1177 1178 return changeDetails; 1179 } 1180 }, { 1181 key: 'value', 1182 get: function get$$1() { 1183 return this._value; 1184 }, 1185 set: function set$$1(value) { 1186 this.resolve(value); 1187 } 1188 }, { 1189 key: 'unmaskedValue', 1190 get: function get$$1() { 1191 return this.value; 1192 }, 1193 set: function set$$1(value) { 1194 this.reset(); 1195 this._append(value); 1196 this._appendTail(); 1197 this.doCommit(); 1198 } 1199 1200 /** Value that includes raw user input */ 1201 1202 }, { 1203 key: 'rawInputValue', 1204 get: function get$$1() { 1205 return this.extractInput(0, this.value.length, { raw: true }); 1206 }, 1207 set: function set$$1(value) { 1208 this.reset(); 1209 this._append(value, { raw: true }); 1210 this._appendTail(); 1211 this.doCommit(); 1212 } 1213 1214 /** */ 1215 1216 }, { 1217 key: 'isComplete', 1218 get: function get$$1() { 1219 return true; 1220 } 1221 }]); 1222 return Masked; 1223}(); 1224 1225Masked.DEFAULTS = { 1226 prepare: function prepare(val) { 1227 return val; 1228 }, 1229 validate: function validate() { 1230 return true; 1231 }, 1232 commit: function commit() {} 1233}; 1234 1235/** Get Masked class by mask type */ 1236function maskedClass(mask) { 1237 if (mask == null) { 1238 throw new Error('mask property should be defined'); 1239 } 1240 1241 if (mask instanceof RegExp) return g.IMask.MaskedRegExp; 1242 if (isString(mask)) return g.IMask.MaskedPattern; 1243 if (mask instanceof Date || mask === Date) return g.IMask.MaskedDate; 1244 if (mask instanceof Number || typeof mask === 'number' || mask === Number) return g.IMask.MaskedNumber; 1245 if (Array.isArray(mask) || mask === Array) return g.IMask.MaskedDynamic; 1246 // $FlowFixMe 1247 if (mask.prototype instanceof g.IMask.Masked) return mask; 1248 // $FlowFixMe 1249 if (mask instanceof Function) return g.IMask.MaskedFunction; 1250 1251 console.warn('Mask not found for mask', mask); // eslint-disable-line no-console 1252 return g.IMask.Masked; 1253} 1254 1255/** Creates new {@link Masked}
1255 depending on mask type */ 1256function createMask(opts) { 1257 opts = _extends({}, opts); // clone 1258 var mask = opts.mask; 1259 1260 if (mask instanceof g.IMask.Masked) return mask; 1261 1262 var MaskedClass = maskedClass(mask); 1263 return new MaskedClass(opts); 1264} 1265 1266/** */ 1267 1268/** */ 1269var PatternDefinition = function () { 1270 /** */ 1271 1272 /** */ 1273 1274 /** */ 1275 function PatternDefinition(opts) { 1276 classCallCheck(this, PatternDefinition); 1277 // TODO flow 1278 _extends(this, opts); 1279 1280 if (this.mask) { 1281 this._masked = createMask(opts); 1282 } 1283 } 1284 1285 /** */ 1286 1287 /** */ 1288 1289 /** */ 1290 1291 /** */ 1292 1293 1294 /** */ 1295 1296 1297 createClass(PatternDefinition, [{ 1298 key: 'reset', 1299 value: function reset() { 1300 this.isHollow = false; 1301 this.isRawInput = false; 1302 if (this._masked) this._masked.reset(); 1303 } 1304 1305 /** */ 1306 1307 }, { 1308 key: 'resolve', 1309 1310 1311 /** */ 1312 value: function resolve(ch) { 1313 if (!this._masked) return false; 1314 return this._masked.resolve(ch); 1315 } 1316 }, { 1317 key: 'isInput', 1318 get: function get$$1() { 1319 return this.type === PatternDefinition.TYPES.INPUT; 1320 } 1321 1322 /** */ 1323 1324 }, { 1325 key: 'isHiddenHollow', 1326 get: function get$$1() { 1327 return this.isHollow && this.optional; 1328 } 1329 }]); 1330 return PatternDefinition; 1331}(); 1332 1333PatternDefinition.DEFAULTS = { 1334 '0': /\d/, 1335 'a': /[\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFB
1335D3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/, // http://stackoverflow.com/a/22075070 1336 '*': /./ 1337}; 1338/** 1339 @prop {string} INPUT 1340 @prop {string} FIXED 1341*/ 1342PatternDefinition.TYPES = { 1343 INPUT: 'input', 1344 FIXED: 'fixed' 1345}; 1346 1347/** */ 1348 1349 1350/** */ 1351 1352/** 1353 Pattern group symbols from parent 1354 @param {MaskedPattern} masked - Internal {@link masked} model 1355 @param {Object} opts 1356 @param {string} opts.name - Group name 1357 @param {number} opts.offset - Group offset in masked definitions array 1358 @param {string} opts.mask - Group mask 1359 @param {Function} [opts.validate] - Custom group validator 1360*/ 1361var PatternGroup = function () { 1362 /** Group mask */ 1363 1364 /** Group name */ 1365 1366 /** */ 1367 function PatternGroup(masked, _ref) { 1368 var name = _ref.name, 1369 offset = _ref.offset, 1370 mask = _ref.mask, 1371 validate = _ref.validate; 1372 classCallCheck(this, PatternGroup); 1373 1374 this.masked = masked; 1375 this.name = name; 1376 this.offset = offset; 1377 this.mask = mask; 1378 this.validate = validate || function () { 1379 return true; 1380 }; 1381 } 1382 1383 /** Slice of internal {@link masked} value */ 1384 1385 /** Custom group validator */ 1386 1387 /** Group offset in masked definitions array */ 1388 1389 1390 /** Internal {@link masked} model */ 1391 1392 /** */ 1393 1394 1395 createClass(PatternGroup, [{ 1396 key: 'doValidate', 1397 1398 1399 /** Validates if current value is acceptable */ 1400 value: function doValidate(flags) { 1401 return this.validate(this.value, this, flags); 1402 } 1403 }, { 1404 key: 'value', 1405 get: function get$$1() { 1406 return this.masked.value.slice(this.masked.mapDefIndexToPos(this.offset), this.masked.mapDefIndexToPos(this.offset + this.mask.length)); 1407 } 1408 1409 /** Unmasked slice of internal {@link masked} value */ 1410 1411 }, { 1412 key: 'unmaskedValue', 1413 get: function get$$1() { 1414 return this.masked.extractInput(this.masked.mapDefIndexToPos(this.offset), this.masked.mapDefIndexToPos(this.offset + this.mask.length)); 1415 } 1416 }]); 1417 return PatternGroup; 1418}(); 1419 1420var RangeGroup = function () { 1421 /** @type {Function} */ 1422 function RangeGroup(_ref2) { 1423 var _ref3 = slicedToArray(_ref2, 2), 1424 from = _ref3[0], 1425 to = _ref3[1]; 1426 1427 var maxlen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : String(to).length; 1428 classCallCheck(this, RangeGroup); 1429 1430 this._from = from; 1431 this._to = to; 1432 this._maxLength = maxlen; 1433 this.validate = this.validate.bind(this); 1434 1435 this._update(); 1436 } 1437 /** @type {string} */ 1438 1439 1440 createClass(RangeGroup, [{ 1441 key: '_update', 1442 value: function _update() { 1443 this._maxLength = Math.max(this._maxLength, String(this.to).length); 1444 this.mask = '0'.repeat(this._maxLength); 1445 } 1446 }, { 1447 key: 'validate', 1448 value: function validate(str) { 1449 var minstr = ''; 1450 var maxstr = ''; 1451 1452 var _ref4 = str.match(/^(\D*)(\d*)(\D*)/) || [], 1453 _ref5 = slicedToArray(_ref4, 3), 1454 placeholder = _ref5[1], 1455 num = _ref5[2]; 1456 1457 if (num) { 1458 minstr = '0'.repeat(placeholder.length) + num; 1459 maxstr = '9'.repeat(placeholder.length) + num; 1460 } 1461 1462 var firstNonZero = str.search(/[^0]/); 1463 if (firstNonZero === -1 && str.length <= this._matchFrom) return true; 1464 1465 minstr = minstr.padEnd(this._maxLength, '0'); 1466 maxstr = maxstr.padEnd(this._maxLength, '9'); 1467 1468 return this.from <= Number(maxstr) && Number(minstr) <= this.to; 1469 } 1470 }, { 1471 key: 'to', 1472 get: function get$$1() { 1473 return this._to; 1474 }, 1475 set: function set$$1(to) { 1476 this._to = to; 1477 this._update(); 1478 } 1479 }, { 1480 key: 'from', 1481 get: function get$$1() { 1482 return this._from; 1483 }, 1484 set: function set$$1(from) { 1485 this._from = from; 1486 this._update(); 1487 } 1488 }, { 1489 key: 'maxLength', 1490 get: function get$$1() { 1491 return this._maxLength; 1492 }, 1493 set: function set$$1(maxLength) { 1494 this._maxLength = maxLength; 1495 this._update(); 1496 } 1497 }, { 1498 key: '_matchFrom', 1499 get: function get$$1() { 1500 return this.maxLength - String(this.from).length; 1501 } 1502 }]); 1503 return RangeGroup; 1504}(); 1505 1506/** Pattern group that validates enum values */ 1507function EnumGroup(enums) { 1508 return { 1509 mask: '*'.repeat(enums[0].length), 1510 validate: function validate(value, group, flags) { 1511 return enums.some(function (e) { 1512 return e.indexOf(group.unmaskedValue) >= 0; 1513 }); 1514 } 1515 }; 1516} 1517 1518PatternGroup.Range = RangeGroup; 1519PatternGroup.Enum = EnumGroup; 1520 1521var ChunksTailDetails = function () { 1522 function ChunksTailDetails(chunks) { 1523 classCallCheck(this, ChunksTailDetails); 1524 1525 this.chunks = chunks; 1526 } 1527 1528 createClass(ChunksTailDetails, [{ 1529 key: 'value', 1530 get: function get$$1() { 1531 return this.chunks.map(function (c) { 1532 return c.value; 1533 }).join(''); 1534 } 1535 }, { 1536 key: 'fromPos', 1537 get: function get$$1() { 1538 var firstChunk = this.chunks[0]; 1539 return firstChunk && firstChunk.stop; 1540 } 1541 }, { 1542 key: 'toPos', 1543 get: function get$$1() { 1544 var lastChunk = this.chunks[this.chunks.length - 1]; 1545 return lastChunk && lastChunk.stop; 1546 } 1547 }]); 1548 return ChunksTailDetails; 1549}(); 1550 1551/** 1552 Pattern mask 1553 @param {Object} opts 1554 @param {Object} opts.groups 1555 @param {Object} opts.definitions 1556 @param {string} opts.placeholderChar 1557 @param {boolean} opts.lazy 1558*/ 1559var MaskedPattern = function (_Masked) { 1560 inherits(MaskedPattern, _Masked); 1561 1562 // TODO mask type 1563 /** Single char for empty input */ 1564 1565 1566 /** */ 1567 function MaskedPattern() { 1568 var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1569 classCallCheck(this, MaskedPattern); 1570 // TODO type $Shape<MaskedPatternOptions>={} does not work 1571 opts.definitions = _extends({}, PatternDefinition.DEFAULTS, opts.definitions); 1572 return possibleConstructorReturn(this, (MaskedPattern.__proto__ || Object.getPrototypeOf(MaskedPattern)).call(this, _extends({}, MaskedPattern.DEFAULTS, opts))); 1573 } 1574 1575 /** 1576 @override 1577 @param {Object} opts 1578 */ 1579 1580 /** Show placeholder only when needed */ 1581 1582 /** */ 1583 1584 1585 createClass(MaskedPattern, [{ 1586 key: '_update', 1587 value: function _update() { 1588 var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1589 1590 opts.definitions = _extends({}, this.definitions, opts.definitions); 1591 get(MaskedPattern.prototype.__proto__ || Object.getPrototypeOf(MaskedPattern.prototype), '_update', this).call(this, opts); 1592 this._rebuildMask(); 1593 } 1594 1595 /** */ 1596 1597 }, { 1598 key: '_rebuildMask', 1599 value: function _rebuildMask() { 1600 var _this2 = this; 1601 1602 var defs = this.definitions; 1603 this._charDefs = []; 1604 this._groupDefs = []; 1605 1606 var pattern = this.mask; 1607 if (!pattern || !defs) return; 1608 1609 var unmaskingBlock = false;
1610 var optionalBlock = false; 1611 var stopAlign = false; 1612 1613 var _loop = function _loop(_i) { 1614 if (_this2.groups) { 1615 var p = pattern.slice(_i); 1616 var gNames = Object.keys(_this2.groups).filter(function (gName) { 1617 return p.indexOf(gName) === 0; 1618 }); 1619 // order by key length 1620 gNames.sort(function (a, b) { 1621 return b.length - a.length; 1622 }); 1623 // use group name with max length 1624 var gName = gNames[0]; 1625 if (gName) { 1626 var group = _this2.groups[gName]; 1627 _this2._groupDefs.push(new PatternGroup(_this2, { 1628 name: gName, 1629 offset: _this2._charDefs.length, 1630 mask: group.mask, 1631 validate: group.validate 1632 })); 1633 pattern = pattern.replace(gName, group.mask); 1634 } 1635 } 1636 1637 var char = pattern[_i]; 1638 var type = char in defs ? PatternDefinition.TYPES.INPUT : PatternDefinition.TYPES.FIXED; 1639 var unmasking = type === PatternDefinition.TYPES.INPUT || unmaskingBlock; 1640 var optional = type === PatternDefinition.TYPES.INPUT && optionalBlock; 1641 1642 if (char === MaskedPattern.STOP_CHAR) { 1643 stopAlign = true; 1644 return 'continue'; 1645 } 1646 1647 if (char === '{' || char === '}') { 1648 unmaskingBlock = !unmaskingBlock; 1649 return 'continue'; 1650 } 1651 1652 if (char === '[' || char === ']') { 1653 optionalBlock = !optionalBlock; 1654 return 'continue'; 1655 } 1656 1657 if (char === MaskedPattern.ESCAPE_CHAR) { 1658 ++_i; 1659 char = pattern[_i]; 1660 if (!char) return 'break'; 1661 type = PatternDefinition.TYPES.FIXED; 1662 } 1663 1664 _this2._charDefs.push(new PatternDefinition({ 1665 char: char, 1666 type: type, 1667 optional: optional, 1668 stopAlign: stopAlign, 1669 unmasking: unmasking, 1670 mask: type === PatternDefinition.TYPES.INPUT ? defs[char] : function (value) { 1671 return value === char; 1672 } 1673 })); 1674 1675 stopAlign = false; 1676 i = _i; 1677 }; 1678 1679 _loop2: for (var i = 0; i < pattern.length; ++i) { 1680 var _ret = _loop(i); 1681 1682 switch (_ret) { 1683 case 'continue': 1684 continue; 1685 1686 case 'break': 1687 break _loop2;} 1688 } 1689 } 1690 1691 /** 1692 @override 1693 */ 1694 1695 }, { 1696 key: 'doValidate', 1697 value: function doValidate() { 1698 var _babelHelpers$get; 1699 1700 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 1701 args[_key] = arguments[_key]; 1702 } 1703 1704 return this._groupDefs.every(function (g$$1) { 1705 return g$$1.doValidate.apply(g$$1, toConsumableArray(args)); 1706 }) && (_babelHelpers$get = get(MaskedPattern.prototype.__proto__ || Object.getPrototypeOf(MaskedPattern.prototype), 'doValidate', this)).call.apply(_babelHelpers$get, [this].concat(toConsumableArray(args))); 1707 } 1708 1709 /** 1710 @override 1711 */ 1712 1713 }, { 1714 key: 'clone', 1715 value: function clone() { 1716 var _this3 = this; 1717 1718 var m = new MaskedPattern(this); 1719 m._value = this.value; 1720 // $FlowFixMe 1721 m._charDefs.forEach(function (d, i) { 1722 return _extends(d, _this3._charDefs[i]); 1723 }); 1724 // $FlowFixMe 1725 m._groupDefs.forEach(function (d, i) { 1726 return _extends(d, _this3._groupDefs[i]); 1727 }); 1728 return m; 1729 } 1730 1731 /** 1732 @override 1733 */ 1734 1735 }, { 1736 key: 'reset', 1737 value: function reset() { 1738 get(MaskedPattern.prototype.__proto__ || Object.getPrototypeOf(MaskedPattern.prototype), 'reset', this).call(this); 1739 this._charDefs.forEach(function (d) { 1740 delete d.isHollow; 1741 }); 1742 } 1743 1744 /** 1745 @override 1746 */ 1747 1748 }, { 1749 key: 'hiddenHollowsBefore', 1750 1751 1752 /** */ 1753 value: function hiddenHollowsBefore(defIndex) { 1754 return this._charDefs.slice(0, defIndex).filter(function (d) { 1755 return d.isHiddenHollow; 1756 }).length; 1757 } 1758 1759 /** Map definition index to position on view */ 1760 1761 }, { 1762 key: 'mapDefIndexToPos', 1763 value: function mapDefIndexToPos(defIndex) { 1764 return defIndex - this.hiddenHollowsBefore(defIndex); 1765 } 1766 1767 /** Map position on view to definition index */ 1768 1769 }, { 1770 key: 'mapPosToDefIndex', 1771 value: function mapPosToDefIndex(pos) { 1772 var defIndex = pos; 1773 for (var di = 0; di < this._charDefs.length; ++di) { 1774 var def = this._charDefs[di]; 1775 if (di >= defIndex) break; 1776 if (def.isHiddenHollow) ++defIndex; 1777 } 1778 return defIndex; 1779 } 1780 1781 /** 1782 @override 1783 */ 1784 1785 }, { 1786 key: '_appendTail', 1787 1788 1789 /** 1790 @override 1791 */ 1792 value: function _appendTail(tail) { 1793 var details = new ChangeDetails(); 1794 if (tail) { 1795 details.aggregate(tail instanceof ChunksTailDetails ? this._appendChunks(tail.chunks, { tail: true }) : get(MaskedPattern.prototype.__proto__ || Object.getPrototypeOf(MaskedPattern.prototype), '_appendTail', this).call(this, tail)); 1796 } 1797 return details.aggregate(this._appendPlaceholder()); 1798 } 1799 1800 /** 1801 @override 1802 */ 1803 1804 }, { 1805 key: '_append', 1806 value: function _append(str) { 1807 var flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 1808 1809 var oldValueLength = this.value.length; 1810 var rawInserted = ''; 1811 var overflow = false;
1812 1813 str = this.doPrepare(str, flags); 1814 1815 for (var ci = 0, di = this.mapPosToDefIndex(this.value.length); ci < str.length;) { 1816 var ch = str[ci]; 1817 var def = this._charDefs[di]; 1818 1819 // check overflow 1820 if (def == null) { 1821 overflow = true; 1822 break; 1823 } 1824 1825 // reset 1826 def.isHollow = false; 1827 1828 var resolved = void 0, 1829 skipped = void 0; 1830 var chres = conform(def.resolve(ch), ch); 1831 1832 if (def.type === PatternDefinition.TYPES.INPUT) { 1833 if (chres) { 1834 this._value += chres; 1835 if (!this.doValidate()) { 1836 chres = ''; 1837 this._value = this.value.slice(0, -1); 1838 } 1839 } 1840 1841 resolved = !!chres; 1842 skipped = !chres && !def.optional; 1843 1844 if (!chres) { 1845 if (!def.optional && !flags.input && !this.lazy) { 1846 this._value += this.placeholderChar; 1847 skipped = false; 1848 } 1849 if (!skipped) def.isHollow = true; 1850 } else { 1851 rawInserted += chres; 1852 } 1853 } else { 1854 this._value += def.char; 1855 resolved = chres && (def.unmasking || flags.input || flags.raw) && !flags.tail; 1856 def.isRawInput = resolved && (flags.raw || flags.input); 1857 if (def.isRawInput) rawInserted += def.char; 1858 } 1859 1860 if (!skipped) ++di; 1861 if (resolved || skipped) ++ci; 1862 } 1863 1864 return new ChangeDetails({ 1865 inserted: this.value.slice(oldValueLength), 1866 rawInserted: rawInserted, 1867 overflow: overflow 1868 }); 1869 } 1870 1871 /** Appends chunks splitted by stop chars */ 1872 1873 }, { 1874 key: '_appendChunks', 1875 value: function _appendChunks(chunks) { 1876 var details = new ChangeDetails(); 1877 1878 for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 1879 args[_key2 - 1] = arguments[_key2]; 1880 } 1881 1882 for (var ci = 0; ci < chunks.length; ++ci) { 1883 var _chunks$ci = chunks[ci], 1884 stop = _chunks$ci.stop, 1885 value = _chunks$ci.value; 1886 1887 var fromDef = stop != null && this._charDefs[stop]; 1888 // lets double check if stopAlign is here 1889 if (fromDef && fromDef.stopAlign) details.aggregate(this._appendPlaceholder(stop)); 1890 if (details.aggregate(this._append.apply(this, [value].concat(toConsumableArray(args)))).overflow) break; 1891 } 1892 return details; 1893 } 1894 1895 /** 1896 @override 1897 */ 1898 1899 }, { 1900 key: '_extractTail', 1901 value: function _extractTail() { 1902 var fromPos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 1903 var toPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length; 1904 1905 return new ChunksTailDetails(this._extractInputChunks(fromPos, toPos)); 1906 } 1907 1908 /** 1909 @override 1910 */ 1911 1912 }, { 1913 key: 'extractInput', 1914 value: function extractInput() { 1915 var fromPos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 1916 var toPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length; 1917 var flags = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 1918 1919 if (fromPos === toPos) return ''; 1920 1921 var str = this.value; 1922 var input = ''; 1923 1924 var toDefIndex = this.mapPosToDefIndex(toPos); 1925 for (var ci = fromPos, di = this.mapPosToDefIndex(fromPos); ci < toPos && ci < str.length && di < toDefIndex; ++di) { 1926 var ch = str[ci]; 1927 var def = this._charDefs[di]; 1928 1929 if (!def) break; 1930 if (def.isHiddenHollow) continue; 1931 1932 if (def.isInput && !def.isHollow || flags.raw && !def.isInput && def.isRawInput) input += ch; 1933 ++ci; 1934 } 1935 return input; 1936 } 1937 1938 /** Extracts chunks from input splitted by stop chars */ 1939 1940 }, { 1941 key: '_extractInputChunks', 1942 value: function _extractInputChunks() { 1943 var _this4 = this; 1944 1945 var fromPos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 1946 var toPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length; 1947 1948 if (fromPos === toPos) return []; 1949 1950 var fromDefIndex = this.mapPosToDefIndex(fromPos); 1951 var toDefIndex = this.mapPosToDefIndex(toPos); 1952 var stopDefIndices = this._charDefs.map(function (d, i) { 1953 return [d, i]; 1954 }).slice(fromDefIndex, toDefIndex).filter(function (_ref) { 1955 var _ref2 = slicedToArray(_ref, 1), 1956 d = _ref2[0]; 1957 1958 return d.stopAlign; 1959 }).map(function (_ref3) { 1960 var _ref4 = slicedToArray(_ref3, 2), 1961 i = _ref4[1]; 1962 1963 return i; 1964 }); 1965 1966 var stops = [fromDefIndex].concat(toConsumableArray(stopDefIndices), [toDefIndex]); 1967 1968 return stops.map(function (s, i) { 1969 return { 1970 stop: stopDefIndices.indexOf(s) >= 0 ? s : null, 1971 1972 value: _this4.extractInput(_this4.mapDefIndexToPos(s), _this4.mapDefIndexToPos(stops[++i])) 1973 }; 1974 }).filter(function (_ref5) { 1975 var stop = _ref5.stop, 1976 value = _ref5.value; 1977 return stop != null || value; 1978 }); 1979 } 1980 1981 /** Appends placeholder depending on laziness */ 1982 1983 }, { 1984 key: '_appendPlaceholder', 1985 value: function _appendPlaceholder(toDefIndex) { 1986 var oldValueLength = this.value.length; 1987 var maxDefIndex = toDefIndex || this._charDefs.length; 1988 for (var di = this.mapPosToDefIndex(this.value.length); di < maxDefIndex; ++di) { 1989 var def = this._charDefs[di]; 1990 if (def.isInput) def.isHollow = true; 1991 1992 if (!this.lazy || toDefIndex) { 1993 this._value += !def.isInput && def.char != null ? def.char : !def.optional ? this.placeholderChar : ''; 1994 } 1995 } 1996 return new ChangeDetails({ 1997 inserted: this.value.slice(oldValueLength) 1998 }); 1999 } 2000 2001 /** 2002 @override 2003 */ 2004 2005 }, { 2006 key: 'remove', 2007 value: function remove() { 2008 var from = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 2009 var count = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length - from; 2010 2011 var fromDefIndex = this.mapPosToDefIndex(from); 2012 var toDefIndex = this.mapPosToDefIndex(from + count);
2013 this._charDefs.slice(fromDefIndex, toDefIndex).forEach(function (d) { 2014 return d.reset(); 2015 }); 2016 2017 return get(MaskedPattern.prototype.__proto__ || Object.getPrototypeOf(MaskedPattern.prototype), 'remove', this).call(this, from, count); 2018 } 2019 2020 /** 2021 @override 2022 */ 2023 2024 }, { 2025 key: 'nearestInputPos', 2026 value: function nearestInputPos(cursorPos) { 2027 var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DIRECTION.NONE; 2028 2029 var step = direction || DIRECTION.RIGHT; 2030 2031 var initialDefIndex = this.mapPosToDefIndex(cursorPos); 2032 var initialDef = this._charDefs[initialDefIndex]; 2033 var di = initialDefIndex; 2034 2035 var firstInputIndex = void 0, 2036 firstFilledInputIndex = void 0, 2037 firstVisibleHollowIndex = void 0, 2038 nextdi = void 0; 2039 2040 // check if chars at right is acceptable for LEFT and NONE directions 2041 if (direction !== DIRECTION.RIGHT && (initialDef && initialDef.isInput || 2042 // in none direction latest position is acceptable also 2043 direction === DIRECTION.NONE && cursorPos === this.value.length)) { 2044 firstInputIndex = initialDefIndex; 2045 if (initialDef && !initialDef.isHollow) firstFilledInputIndex = initialDefIndex; 2046 } 2047 2048 if (firstFilledInputIndex == null && direction == DIRECTION.LEFT || firstInputIndex == null) { 2049 // search forward 2050 for (nextdi = indexInDirection(di, step); 0 <= nextdi && nextdi < this._charDefs.length; di += step, nextdi += step) { 2051 var nextDef = this._charDefs[nextdi]; 2052 if (firstInputIndex == null && nextDef.isInput) { 2053 firstInputIndex = di; 2054 if (direction === DIRECTION.NONE) break; 2055 } 2056 if (firstVisibleHollowIndex == null && nextDef.isHollow && !nextDef.isHiddenHollow) firstVisibleHollowIndex = di; 2057 if (nextDef.isInput && !nextDef.isHollow) { 2058 firstFilledInputIndex = di; 2059 break; 2060 } 2061 } 2062 } 2063 2064 // for lazy if has aligned left inside fixed and has came to the start - use start position 2065 if (direction === DIRECTION.LEFT && di === 0 && this.lazy && !this.extractInput() && (!initialDef || !initialDef.isInput)) firstInputIndex = 0; 2066 2067 if (direction === DIRECTION.LEFT || firstInputIndex == null) { 2068 // search backward 2069 step = -step; 2070 var overflow = false; 2071 2072 // find hollows only before initial pos 2073 for (nextdi = indexInDirection(di, step); 0 <= nextdi && nextdi < this._charDefs.length; di += step, nextdi += step) { 2074 var _nextDef = this._charDefs[nextdi]; 2075 if (_nextDef.isInput) { 2076 firstInputIndex = di; 2077 if (_nextDef.isHollow && !_nextDef.isHiddenHollow) break; 2078 } 2079 2080 // if hollow not found before start position - set `overflow` 2081 // and try to find just any input 2082 if (di === initialDefIndex) overflow = true; 2083 2084 // first input found 2085 if (overflow && firstInputIndex != null) break; 2086 } 2087 2088 // process overflow 2089 overflow = overflow || nextdi >= this._charDefs.length; 2090 if (overflow && firstInputIndex != null) di = firstInputIndex; 2091 } else if (firstFilledInputIndex == null) { 2092 // adjust index if delete at right and filled input not found at right 2093 di = firstVisibleHollowIndex != null ? firstVisibleHollowIndex : firstInputIndex; 2094 } 2095 2096 return this.mapDefIndexToPos(di); 2097 } 2098 2099 /** Get group by name */ 2100 2101 }, { 2102 key: 'group', 2103 value: function group(name) { 2104 return this.groupsByName(name)[0]; 2105 } 2106 2107 /** Get all groups by name */ 2108 2109 }, { 2110 key: 'groupsByName', 2111 value: function groupsByName(name) { 2112 return this._groupDefs.filter(function (g$$1) { 2113 return g$$1.name === name; 2114 }); 2115 } 2116 }, { 2117 key: 'isComplete', 2118 get: function get$$1() { 2119 var _this5 = this; 2120 2121 return !this._charDefs.some(function (d, i) { 2122 return d.isInput && !d.optional && (d.isHollow || !_this5.extractInput(i, i + 1)); 2123 }); 2124 } 2125 }, { 2126 key: 'unmaskedValue', 2127 get: function get$$1() { 2128 var str = this.value; 2129 var unmasked = ''; 2130 2131 for (var ci = 0, di = 0; ci < str.length && di < this._charDefs.length; ++di) { 2132 var ch = str[ci]; 2133 var def = this._charDefs[di]; 2134 2135 if (def.isHiddenHollow) continue; 2136 if (def.unmasking && !def.isHollow) unmasked += ch; 2137 ++ci; 2138 } 2139 2140 return unmasked; 2141 }, 2142 set: function set$$1(unmaskedValue) { 2143 set(MaskedPattern.prototype.__proto__ || Object.getPrototypeOf(MaskedPattern.prototype), 'unmaskedValue', unmaskedValue, this); 2144 } 2145 }]); 2146 return MaskedPattern; 2147}(Masked); 2148 2149MaskedPattern.DEFAULTS = { 2150 lazy: true, 2151 placeholderChar: '_' 2152}; 2153MaskedPattern.STOP_CHAR = '`'; 2154MaskedPattern.ESCAPE_CHAR = '\\'; 2155MaskedPattern.Definition = PatternDefinition; 2156MaskedPattern.Group = PatternGroup; 2157 2158/** Date mask */ 2159 2160var MaskedDate = function (_MaskedPattern) { 2161 inherits(MaskedDate, _MaskedPattern); 2162 2163 /** 2164 @param {Object} opts 2165 */ 2166 2167 /** Start date */ 2168 2169 /** Format Date to string */ 2170 function MaskedDate(opts) { 2171 classCallCheck(this, MaskedDate); 2172 return possibleConstructorReturn(this, (MaskedDate.__proto__ || Object.getPrototypeOf(MaskedDate)).call(this, _extends({}, MaskedDate.DEFAULTS, opts))); 2173 } 2174 2175 /** 2176 @override 2177 */ 2178 2179 /** End date */ 2180 2181 /** Pattern mask for date according to {@link MaskedDate#format} */ 2182 2183 2184 /** Parse string to Date */ 2185 2186 2187 createClass(MaskedDate, [{ 2188 key: '_update', 2189 value: function _update(opts) { 2190 if (opts.mask === Date) delete opts.mask; 2191 if (opts.pattern) { 2192 opts.mask = opts.pattern; 2193 delete opts.pattern; 2194 } 2195 2196 var groups = opts.groups; 2197 opts.groups = _extends({}, MaskedDate.GET_DEFAULT_GROUPS()); 2198 // adjust year group 2199 if (opts.min) opts.groups.Y.from = opts.min.getFullYear(); 2200 if (opts.max) opts.groups.Y.to = opts.max.getFullYear(); 2201 _extends(opts.groups, groups); 2202 2203 get(MaskedDate.prototype.__proto__ || Object.getPrototypeOf(MaskedDate.prototype), '_update', this).call(this, opts); 2204 } 2205 2206 /** 2207 @override 2208 */ 2209 2210 }, { 2211 key: 'doValidate', 2212 value: function doValidate() { 2213 var _babelHelpers$get; 2214 2215 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 2216 args[_key] = arguments[_key]; 2217 } 2218
2219 var valid = (_babelHelpers$get = get(MaskedDate.prototype.__proto__ || Object.getPrototypeOf(MaskedDate.prototype), 'doValidate', this)).call.apply(_babelHelpers$get, [this].concat(toConsumableArray(args))); 2220 var date = this.date; 2221 2222 return valid && (!this.isComplete || this.isDateExist(this.value) && date && (this.min == null || this.min <= date) && (this.max == null || date <= this.max)); 2223 } 2224 2225 /** Checks if date is exists */ 2226 2227 }, { 2228 key: 'isDateExist', 2229 value: function isDateExist(str) { 2230 return this.format(this.parse(str)) === str; 2231 } 2232 2233 /** Parsed Date */ 2234 2235 }, { 2236 key: 'date', 2237 get: function get$$1() { 2238 return this.isComplete ? this.parse(this.value) : null; 2239 }, 2240 set: function set$$1(date) { 2241 this.value = this.format(date); 2242 } 2243 }]); 2244 return MaskedDate; 2245}(MaskedPattern); 2246 2247MaskedDate.DEFAULTS = { 2248 pattern: 'd{.}`m{.}`Y', 2249 format: function format(date) { 2250 var day = String(date.getDate()).padStart(2, '0'); 2251 var month = String(date.getMonth() + 1).padStart(2, '0'); 2252 var year = date.getFullYear(); 2253 2254 return [day, month, year].join('.'); 2255 }, 2256 parse: function parse(str) { 2257 var _str$split = str.split('.'), 2258 _str$split2 = slicedToArray(_str$split, 3), 2259 day = _str$split2[0], 2260 month = _str$split2[1], 2261 year = _str$split2[2]; 2262 2263 return new Date(year, month - 1, day); 2264 } 2265}; 2266MaskedDate.GET_DEFAULT_GROUPS = function () { 2267 return { 2268 d: new PatternGroup.Range([1, 31]), 2269 m: new PatternGroup.Range([1, 12]), 2270 Y: new PatternGroup.Range([1900, 9999]) 2271 }; 2272}; 2273 2274/** 2275 Generic element API to use with mask 2276 @interface 2277*/ 2278 2279/** Listens to element events and controls changes between element and {@link Masked} */ 2280var InputMask = function () { 2281 2282 /** 2283 @param {UIElement} el 2284 @param {Object} opts 2285 */ 2286 2287 /** 2288 View element 2289 @readonly 2290 */ 2291 function InputMask(el, opts) { 2292 classCallCheck(this, InputMask); 2293 2294 this.el = el; 2295 this.masked = createMask(opts); 2296 2297 this._listeners = {}; 2298 this._value = ''; 2299 this._unmaskedValue = ''; 2300 2301 this._saveSelection = this._saveSelection.bind(this); 2302 this._onInput = this._onInput.bind(this); 2303 this._onChange = this._onChange.bind(this); 2304 this._onDrop = this._onDrop.bind(this); 2305 this.alignCursor = this.alignCursor.bind(this); 2306 this.alignCursorFriendly = this.alignCursorFriendly.bind(this); 2307 2308 this._bindEvents(); 2309 2310 // refresh 2311 this.updateValue(); 2312 this._onChange(); 2313 } 2314 2315 /** Read or update mask */ 2316 2317 2318 /** 2319 Internal {@link Masked} model 2320 @readonly 2321 */ 2322 2323 2324 createClass(InputMask, [{ 2325 key: '_bindEvents', 2326 2327 2328 /** 2329 Starts listening to element events 2330 @protected 2331 */ 2332 value: function _bindEvents() { 2333 this.el.addEventListener('keydown', this._saveSelection); 2334 this.el.addEventListener('input', this._onInput); 2335 this.el.addEventListener('drop', this._onDrop); 2336 this.el.addEventListener('click', this.alignCursorFriendly); 2337 this.el.addEventListener('change', this._onChange); 2338 } 2339 2340 /** 2341 Stops listening to element events 2342 @protected 2343 */ 2344 2345 }, { 2346 key: '_unbindEvents', 2347 value: function _unbindEvents() { 2348 this.el.removeEventListener('keydown', this._saveSelection); 2349 this.el.removeEventListener('input', this._onInput); 2350 this.el.removeEventListener('drop', this._onDrop); 2351 this.el.removeEventListener('click', this.alignCursorFriendly); 2352 this.el.removeEventListener('change', this._onChange); 2353 } 2354 2355 /** 2356 Fires custom event 2357 @protected 2358 */ 2359 2360 }, { 2361 key: '_fireEvent', 2362 value: function _fireEvent(ev) { 2363 var listeners = this._listeners[ev] || []; 2364 listeners.forEach(function (l) { 2365 return l(); 2366 }); 2367 } 2368 2369 /** 2370 Current selection start 2371 @readonly 2372 */ 2373 2374 }, { 2375 key: '_saveSelection', 2376 2377 2378 /** 2379 Stores current selection 2380 @protected 2381 */ 2382 value: function _saveSelection() /* ev */{ 2383 if (this.value !== this.el.value) { 2384 console.warn('Uncontrolled input change, refresh mask manually!'); // eslint-disable-line no-console 2385 } 2386 this._selection = { 2387 start: this.selectionStart, 2388 end: this.cursorPos 2389 }; 2390 } 2391 2392 /** Syncronizes model value from view */ 2393 2394 }, { 2395 key: 'updateValue', 2396 value: function updateValue() { 2397 this.masked.value = this.el.value; 2398 } 2399 2400 /** Syncronizes view from model value, fires change events */ 2401 2402 }, { 2403 key: 'updateControl', 2404 value: function updateControl() { 2405 var newUnmaskedValue = this.masked.unmaskedValue; 2406 var newValue = this.masked.value; 2407 var isChanged = this.unmaskedValue !== newUnmaskedValue || this.value !== newValue; 2408 2409 this._unmaskedValue = newUnmaskedValue; 2410 this._value = newValue; 2411 2412 if (this.el.value !== newValue) this.el.value = newValue; 2413 if (isChanged) this._fireChangeEvents(); 2414 } 2415 2416 /** Updates options with deep equal check, recreates @{link Masked} model if mask type changes */ 2417 2418 }, { 2419 key: 'updateOptions', 2420 value: function updateOptions(opts) { 2421 opts = _extends({}, opts); // clone 2422 if (opts.mask === Date && this.masked instanceof MaskedDate) delete opts.mask; 2423 2424 // check if changed 2425 if (objectIncludes(this.masked, opts)) return; 2426 2427 this.masked.updateOptions(opts); 2428 this.updateControl(); 2429 } 2430
2431 /** Updates cursor */ 2432 2433 }, { 2434 key: 'updateCursor', 2435 value: function updateCursor(cursorPos) { 2436 if (cursorPos == null) return; 2437 this.cursorPos = cursorPos; 2438 2439 // also queue change cursor for mobile browsers 2440 this._delayUpdateCursor(cursorPos); 2441 } 2442 2443 /** 2444 Delays cursor update to support mobile browsers 2445 @private 2446 */ 2447 2448 }, { 2449 key: '_delayUpdateCursor', 2450 value: function _delayUpdateCursor(cursorPos) { 2451 var _this = this; 2452 2453 this._abortUpdateCursor(); 2454 this._changingCursorPos = cursorPos; 2455 this._cursorChanging = setTimeout(function () { 2456 if (!_this.el) return; // if was destroyed 2457 _this.cursorPos = _this._changingCursorPos; 2458 _this._abortUpdateCursor(); 2459 }, 10); 2460 } 2461 2462 /** 2463 Fires custom events 2464 @protected 2465 */ 2466 2467 }, { 2468 key: '_fireChangeEvents', 2469 value: function _fireChangeEvents() { 2470 this._fireEvent('accept'); 2471 if (this.masked.isComplete) this._fireEvent('complete'); 2472 } 2473 2474 /** 2475 Aborts delayed cursor update 2476 @private 2477 */ 2478 2479 }, { 2480 key: '_abortUpdateCursor', 2481 value: function _abortUpdateCursor() { 2482 if (this._cursorChanging) { 2483 clearTimeout(this._cursorChanging); 2484 delete this._cursorChanging; 2485 } 2486 } 2487 2488 /** Aligns cursor to nearest available position */ 2489 2490 }, { 2491 key: 'alignCursor', 2492 value: function alignCursor() {
2493 this.cursorPos = this.masked.nearestInputPos(this.cursorPos, DIRECTION.LEFT); 2494 } 2495 2496 /** Aligns cursor only if selection is empty */ 2497 2498 }, { 2499 key: 'alignCursorFriendly', 2500 value: function alignCursorFriendly() { 2501 if (this.selectionStart !== this.cursorPos) return; 2502 this.alignCursor(); 2503 } 2504 2505 /** Adds listener on custom event */ 2506 2507 }, { 2508 key: 'on', 2509 value: function on(ev, handler) { 2510 if (!this._listeners[ev]) this._listeners[ev] = []; 2511 this._listeners[ev].push(handler); 2512 return this; 2513 } 2514 2515 /** Removes custom event listener */ 2516 2517 }, { 2518 key: 'off', 2519 value: function off(ev, handler) { 2520 if (!this._listeners[ev]) return; 2521 if (!handler) { 2522 delete this._listeners[ev]; 2523 return; 2524 } 2525 var hIndex = this._listeners[ev].indexOf(handler); 2526 if (hIndex >= 0) this._listeners[ev].splice(hIndex, 1); 2527 return this; 2528 } 2529 2530 /** Handles view input event */ 2531 2532 }, { 2533 key: '_onInput', 2534 value: function _onInput() { 2535 this._abortUpdateCursor(); 2536 2537 var details = new ActionDetails( 2538 // new state 2539 this.el.value, this.cursorPos, 2540 // old state 2541 this.value, this._selection); 2542 2543 var offset = this.masked.splice(details.startChangePos, details.removed.length, details.inserted, details.removeDirection).offset; 2544 2545 var cursorPos = this.masked.nearestInputPos(details.startChangePos + offset, details.removeDirection); 2546 2547 this.updateControl(); 2548 this.updateCursor(cursorPos); 2549 } 2550 2551 /** Handles view change event and commits model value */ 2552 2553 }, { 2554 key: '_onChange', 2555 value: function _onChange() { 2556 if (this.value !== this.el.value) { 2557 this.updateValue(); 2558 } 2559 this.masked.doCommit(); 2560 this.updateControl(); 2561 } 2562 2563 /** Handles view drop event, prevents by default */ 2564 2565 }, { 2566 key: '_onDrop', 2567 value: function _onDrop(ev) { 2568 ev.preventDefault(); 2569 ev.stopPropagation(); 2570 } 2571 2572 /** Unbind view events and removes element reference */ 2573 2574 }, { 2575 key: 'destroy', 2576 value: function destroy() { 2577 this._unbindEvents(); 2578 // $FlowFixMe why not do so? 2579 this._listeners.length = 0; 2580 delete this.el; 2581 } 2582 }, { 2583 key: 'mask', 2584 get: function get$$1() { 2585 return this.masked.mask; 2586 }, 2587 set: function set$$1(mask) { 2588 if (mask == null || mask === this.masked.mask) return; 2589 2590 if (this.masked.constructor === maskedClass(mask)) { 2591 this.masked.mask = mask; 2592 return; 2593 } 2594 2595 var masked = createMask({ mask: mask }); 2596 masked.unmaskedValue = this.masked.unmaskedValue; 2597 this.masked = masked; 2598 } 2599 2600 /** Raw value */ 2601 2602 }, { 2603 key: 'value', 2604 get: function get$$1() { 2605 return this._value; 2606 }, 2607 set: function set$$1(str) { 2608 this.masked.value = str; 2609 this.updateControl(); 2610 this.alignCursor(); 2611 } 2612 2613 /** Unmasked value */ 2614 2615 }, { 2616 key: 'unmaskedValue', 2617 get: function get$$1() { 2618 return this._unmaskedValue; 2619 }, 2620 set: function set$$1(str) { 2621 this.masked.unmaskedValue = str; 2622 this.updateControl(); 2623 this.alignCursor(); 2624 } 2625 }, { 2626 key: 'selectionStart', 2627 get: function get$$1() { 2628 return this._cursorChanging ? this._changingCursorPos : this.el.selectionStart; 2629 } 2630 2631 /** Current cursor position */ 2632 2633 }, { 2634 key: 'cursorPos', 2635 get: function get$$1() { 2636 return this._cursorChanging ? this._changingCursorPos : this.el.selectionEnd; 2637 }, 2638 set: function set$$1(pos) { 2639 if (this.el !== document.activeElement) return; 2640 2641 this.el.setSelectionRange(pos, pos); 2642 this._saveSelection(); 2643 } 2644 }]); 2645 return InputMask; 2646}(); 2647 2648/** 2649 Number mask 2650 @param {Object} opts 2651 @param {string} opts.radix - Single char 2652 @param {string} opts.thousandsSeparator - Single char 2653 @param {Array<string>} opts.mapToRadix - Array of single chars 2654 @param {number} opts.min 2655 @param {number} opts.max 2656 @param {number} opts.scale - Digits after point 2657 @param {boolean} opts.signed - Allow negative 2658 @param {boolean} opts.normalizeZeros - Flag to remove leading and trailing zeros in the end of editing 2659 @param {boolean} opts.padFractionalZeros - Flag to pad trailing zeros after point in the end of editing 2660*/ 2661var MaskedNumber = function (_Masked) { 2662 inherits(MaskedNumber, _Masked); 2663 2664 /** Flag to remove leading and trailing zeros in the end of editing */ 2665 2666 /** Digits after point */ 2667 2668 /** */ 2669 2670 /** Single char */ 2671 function MaskedNumber(opts) { 2672 classCallCheck(this, MaskedNumber); 2673 return possibleConstructorReturn(this, (MaskedNumber.__proto__ || Object.getPrototypeOf(MaskedNumber)).call(this, _extends({}, MaskedNumber.DEFAULTS, opts))); 2674 } 2675 2676 /** 2677 @override 2678 */ 2679 2680 /** Flag to pad trailing zeros after point in the end of editing */ 2681 2682 /** */ 2683 2684 /** */ 2685 2686 /** Array of single chars */ 2687 2688 2689 /** Single char */ 2690 2691 2692 createClass(MaskedNumber, [{ 2693 key: '_update', 2694 value: function _update(opts) { 2695 get(MaskedNumber.prototype.__proto__ || Object.getPrototypeOf(MaskedNumber.prototype), '_update', this).call(this, opts); 2696 this._updateRegExps(); 2697 } 2698 2699 /** */ 2700 2701 }, { 2702 key: '_updateRegExps', 2703 value: function _updateRegExps() { 2704 // use different regexp to process user input (more strict, input suffix
2704) and tail shifting 2705 var start = '^'; 2706 2707 var midInput = ''; 2708 var mid = ''; 2709 if (this.allowNegative) { 2710 midInput += '([+|\\-]?|([+|\\-]?(0|([1-9]+\\d*))))'; 2711 mid += '[+|\\-]?'; 2712 } else { 2713 midInput += '(0|([1-9]+\\d*))'; 2714 } 2715 mid += '\\d*'; 2716 2717 var end = (this.scale ? '(' + this.radix + '\\d{0,' + this.scale + '})?' : '') + '$'; 2718 2719 this._numberRegExpInput = new RegExp(start + midInput + end); 2720 this._numberRegExp = new RegExp(start + mid + end); 2721 this._mapToRadixRegExp = new RegExp('[' + this.mapToRadix.map(escapeRegExp).join('') + ']', 'g'); 2722 this._thousandsSeparatorRegExp = new RegExp(escapeRegExp(this.thousandsSeparator), 'g'); 2723 } 2724 2725 /** 2726 @override 2727 */ 2728 2729 }, { 2730 key: '_extractTail', 2731 value: function _extractTail() { 2732 var fromPos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 2733 var toPos = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.value.length; 2734 2735 var tail = get(MaskedNumber.prototype.__proto__ || Object.getPrototypeOf(MaskedNumber.prototype), '_extractTail', this).call(this, fromPos, toPos); 2736 2737 return _extends({}, tail, { 2738 value: this._removeThousandsSeparators(tail.value) 2739 }); 2740 } 2741 2742 /** */ 2743 2744 }, { 2745 key: '_removeThousandsSeparators', 2746 value: function _removeThousandsSeparators(value) { 2747 return value.replace(this._thousandsSeparatorRegExp, ''); 2748 } 2749 2750 /** */ 2751 2752 }, { 2753 key: '_insertThousandsSeparators', 2754 value: function _insertThousandsSeparators(value) { 2755 // https://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript 2756 var parts = value.split(this.radix); 2757 parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, this.thousandsSeparator); 2758 return parts.join(this.radix); 2759 } 2760 2761 /** 2762 @override 2763 */ 2764 2765 }, { 2766 key: 'doPrepare', 2767 value: function doPrepare(str) { 2768 var _babelHelpers$get; 2769 2770 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 2771 args[_key - 1] = arguments[_key]; 2772 } 2773 2774 return (_babelHelpers$get = get(MaskedNumber.prototype.__proto__ || Object.getPrototypeOf(MaskedNumber.prototype), 'doPrepare', this)).call.apply(_babelHelpers$get, [this, this._removeThousandsSeparators(str.replace(this._mapToRadixRegExp, this.radix))].concat(toConsumableArray(args))); 2775 } 2776 2777 /** 2778 @override 2779 */ 2780 2781 }, { 2782 key: 'appendWithTail', 2783 value: function appendWithTail() { 2784 var _babelHelpers$get2; 2785 2786 var previousValue = this.value; 2787 this._value = this._removeThousandsSeparators(this.value); 2788 var startChangePos = this.value.length; 2789 2790 for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 2791 args[_key2] = arguments[_key2]; 2792 } 2793 2794 var appendDetails = (_babelHelpers$get2 = get(MaskedNumber.prototype.__proto__ || Object.getPrototypeOf(MaskedNumber.prototype), 'appendWithTail', this)).call.apply(_babelHelpers$get2, [this].concat(toConsumableArray(args))); 2795 this._value = this._insertThousandsSeparators(this.value); 2796 2797 // calculate offsets after insert separators 2798 var beforeTailPos = startChangePos + appendDetails.inserted.length; 2799 for (var pos = 0; pos <= beforeTailPos; ++pos) { 2800 if (this.value[pos] === this.thousandsSeparator) { 2801 if (pos < startChangePos || 2802 // check high bound 2803 // if separator is still there - consider it also 2804 pos === startChangePos && previousValue[pos] === this.thousandsSeparator) { 2805 ++startChangePos; 2806 } 2807 if (pos < beforeTailPos) ++beforeTailPos; 2808 } 2809 } 2810 2811 // adjust details with separators 2812 appendDetails.rawInserted = appendDetails.inserted; 2813 appendDetails.inserted = this.value.slice(startChangePos, beforeTailPos); 2814 appendDetails.shift += startChangePos - previousValue.length; 2815 2816 return appendDetails; 2817 } 2818 2819 /** 2820 @override 2821 */ 2822 2823 }, { 2824 key: 'nearestInputPos', 2825 value: function nearestInputPos(cursorPos, direction) { 2826 if (!direction) return cursorPos; 2827 2828 var nextPos = indexInDirection(cursorPos, direction); 2829 if (this.value[nextPos] === this.thousandsSeparator) cursorPos += direction; 2830 return cursorPos; 2831 } 2832 2833 /** 2834 @override 2835 */ 2836 2837 }, { 2838 key: 'doValidate', 2839 value: function doValidate(flags) { 2840 var regexp = flags.input ? this._numberRegExpInput : this._numberRegExp; 2841 2842 // validate as string
2843 var valid = regexp.test(this._removeThousandsSeparators(this.value)); 2844 2845 if (valid) { 2846 // validate as number 2847 var number = this.number; 2848 valid = valid && !isNaN(number) && ( 2849 // check min bound for negative values 2850 this.min == null || this.min >= 0 || this.min <= this.number) && ( 2851 // check max bound for positive values 2852 this.max == null || this.max <= 0 || this.number <= this.max); 2853 } 2854 2855 return valid && get(MaskedNumber.prototype.__proto__ || Object.getPrototypeOf(MaskedNumber.prototype), 'doValidate', this).call(this, flags); 2856 } 2857 2858 /** 2859 @override 2860 */ 2861 2862 }, { 2863 key: 'doCommit', 2864 value: function doCommit() { 2865 var number = this.number; 2866 var validnum = number; 2867 2868 // check bounds 2869 if (this.min != null) validnum = Math.max(validnum, this.min); 2870 if (this.max != null) validnum = Math.min(validnum, this.max); 2871 2872 if (validnum !== number) this.unmaskedValue = String(validnum); 2873 2874 var formatted = this.value; 2875 2876 if (this.normalizeZeros) formatted = this._normalizeZeros(formatted); 2877 if (this.padFractionalZeros) formatted = this._padFractionalZeros(formatted); 2878 2879 this._value = formatted; 2880 get(MaskedNumber.prototype.__proto__ || Object.getPrototypeOf(MaskedNumber.prototype), 'doCommit', this).call(this); 2881 } 2882 2883 /** */ 2884 2885 }, { 2886 key: '_normalizeZeros', 2887 value: function _normalizeZeros(value) { 2888 var parts = this._removeThousandsSeparators(value).split(this.radix); 2889 2890 // remove leading zeros 2891 parts[0] = parts[0].replace(/^(\D*)(0*)(\d*)/, function (match, sign, zeros, num) { 2892 return sign + num; 2893 }); 2894 // add leading zero 2895 if (value.length && !/\d$/.test(parts[0])) parts[0] = parts[0] + '0'; 2896 2897 if (parts.length > 1) { 2898 parts[1] = parts[1].replace(/0*$/, ''); // remove trailing zeros 2899 if (!parts[1].length) parts.length = 1; // remove fractional 2900 } 2901 2902 return this._insertThousandsSeparators(parts.join(this.radix)); 2903 } 2904 2905 /** */ 2906 2907 }, { 2908 key: '_padFractionalZeros', 2909 value: function _padFractionalZeros(value) { 2910 if (!value) return value; 2911 2912 var parts = value.split(this.radix); 2913 if (parts.length < 2) parts.push(''); 2914 parts[1] = parts[1].padEnd(this.scale, '0'); 2915 return parts.join(this.radix); 2916 } 2917 2918 /** 2919 @override 2920 */ 2921 2922 }, { 2923 key: 'unmaskedValue', 2924 get: function get$$1() { 2925 return this._removeThousandsSeparators(this._normalizeZeros(this.value)).replace(this.radix, '.'); 2926 }, 2927 set: function set$$1(unmaskedValue) { 2928 set(MaskedNumber.prototype.__proto__ || Object.getPrototypeOf(MaskedNumber.prototype), 'unmaskedValue', unmaskedValue.replace('.', this.radix), this); 2929 } 2930 2931 /** Parsed Number */ 2932 2933 }, { 2934 key: 'number', 2935 get: function get$$1() { 2936 return Number(this.unmaskedValue); 2937 }, 2938 set: function set$$1(number) { 2939 this.unmaskedValue = String(number); 2940 } 2941 2942 /** 2943 Is negative allowed 2944 @readonly 2945 */ 2946 2947 }, { 2948 key: 'allowNegative', 2949 get: function get$$1() { 2950 return this.signed || this.min != null && this.min < 0 || this.max != null && this.max < 0; 2951 } 2952 }]); 2953 return MaskedNumber; 2954}(Masked); 2955 2956MaskedNumber.DEFAULTS = { 2957 radix: ',', 2958 thousandsSeparator: '', 2959 mapToRadix: ['.'], 2960 scale: 2, 2961 signed: false, 2962 normalizeZeros: true, 2963 padFractionalZeros: false 2964}; 2965 2966/** Masking by RegExp */ 2967 2968var MaskedRegExp = function (_Masked) { 2969 inherits(MaskedRegExp, _Masked); 2970 2971 function MaskedRegExp() { 2972 classCallCheck(this, MaskedRegExp); 2973 return possibleConstructorReturn(this, (MaskedRegExp.__proto__ || Object.getPrototypeOf(MaskedRegExp)).apply(this, arguments)); 2974 } 2975 2976 createClass(MaskedRegExp, [{ 2977 key: '_update', 2978 2979 /** 2980 @override 2981 @param {Object} opts 2982 */ 2983 value: function _update(opts) { 2984 opts.validate = function (value) { 2985 return value.search(opts.mask) >= 0; 2986 }; 2987 get(MaskedRegExp.prototype.__proto__ || Object.getPrototypeOf(MaskedRegExp.prototype), '_update', this).call(this, opts); 2988 } 2989 }]); 2990 return MaskedRegExp; 2991}(Masked); 2992 2993/** Masking by custom Function */ 2994 2995var MaskedFunction = function (_Masked) { 2996 inherits(MaskedFunction, _Masked); 2997 2998 function MaskedFunction() { 2999 classCallCheck(this, MaskedFunction); 3000 return possibleConstructorReturn(this, (MaskedFunction.__proto__ || Object.getPrototypeOf(MaskedFunction)).apply(this, arguments)); 3001 } 3002 3003 createClass(MaskedFunction, [{ 3004 key: '_update', 3005 3006 /** 3007 @override 3008 @param {Object} opts 3009 */ 3010 value: function _update(opts) { 3011 opts.validate = opts.mask; 3012 get(MaskedFunction.prototype.__proto__ || Object.getPrototypeOf(MaskedFunction.prototype), '_update', this).call(this, opts); 3013 } 3014 }]); 3015 return MaskedFunction; 3016}(Masked); 3017 3018/** Dynamic mask for choosing apropriate mask in run-time */ 3019var MaskedDynamic = function (_Masked) { 3020 inherits(MaskedDynamic, _Masked); 3021 3022 /** 3023 @param {Object} opts 3024 */ 3025 3026 /** Compliled {@link Masked} options */ 3027 function MaskedDynamic(opts) { 3028 classCallCheck(this, MaskedDynamic); 3029 3030 var _this = possibleConstructorReturn(this, (MaskedDynamic.__proto__ || Object.getPrototypeOf(MaskedDynamic)).call(this, _extends({}, MaskedDynamic.DEFAULTS, opts))); 3031 3032 _this.currentMask = null; 3033 return _this; 3034 } 3035 3036 /** 3037 @override 3038 */ 3039 3040 /** Chooses {@link Masked}
3040 depending on input value */ 3041 3042 /** Currently chosen mask */ 3043 3044 3045 createClass(MaskedDynamic, [{ 3046 key: '_update', 3047 value: function _update(opts) { 3048 get(MaskedDynamic.prototype.__proto__ || Object.getPrototypeOf(MaskedDynamic.prototype), '_update', this).call(this, opts); 3049 // mask could be totally dynamic with only `dispatch` option 3050 this.compiledMasks = Array.isArray(opts.mask) ? opts.mask.map(function (m) { 3051 return createMask(m); 3052 }) : []; 3053 } 3054 3055 /** 3056 @override 3057 */ 3058 3059 }, { 3060 key: '_append', 3061 value: function _append(str) { 3062 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 3063 args[_key - 1] = arguments[_key]; 3064 } 3065 3066 str = this.doPrepare.apply(this, [str].concat(toConsumableArray(args))); 3067 3068 var details = this._applyDispatch.apply(this, [str].concat(toConsumableArray(args))); 3069 3070 if (this.currentMask) { 3071 var _currentMask; 3072 3073 details.aggregate((_currentMask = this.currentMask)._append.apply(_currentMask, [str].concat(toConsumableArray(args)))); 3074 } 3075 3076 return details; 3077 } 3078 }, { 3079 key: '_applyDispatch', 3080 value: function _applyDispatch() { 3081 var appended = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 3082 3083 var oldValueLength = this.value.length; 3084 var inputValue = this.rawInputValue; 3085 var oldMask = this.currentMask; 3086 var details = new ChangeDetails(); 3087 3088 // dispatch SHOULD NOT modify mask 3089 3090 for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 3091 args[_key2 - 1] = arguments[_key2]; 3092 } 3093 3094 this.currentMask = this.doDispatch.apply(this, [appended].concat(toConsumableArray(args))); 3095 3096 // restore state after dispatch 3097 if (this.currentMask && this.currentMask !== oldMask) { 3098 // if mask changed reapply input 3099 this.currentMask.reset(); 3100 // $FlowFixMe - it's ok, we don't change current mask 3101 this.currentMask._append(inputValue, { raw: true }); 3102 details.shift = this.value.length - oldValueLength; 3103 } 3104 3105 return details; 3106 } 3107 3108 /** 3109 @override 3110 */ 3111 3112 }, { 3113 key: 'doDispatch', 3114 value: function doDispatch(appended) { 3115 var flags = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 3116 3117 return this.dispatch(appended, this, flags); 3118 } 3119 3120 /** 3121 @override 3122 */ 3123 3124 }, { 3125 key: 'clone', 3126 value: function clone() { 3127 var m = new MaskedDynamic(this); 3128 m._value = this.value; 3129 3130 // try to keep reference to compiled masks 3131 var currentMaskIndex = this.compiledMasks.indexOf(this.currentMask); 3132 if (this.currentMask) { 3133 m.currentMask = currentMaskIndex >= 0 ? m.compiledMasks[currentMaskIndex].assign(this.currentMask) : this.currentMask.clone(); 3134 } 3135 3136 return m; 3137 } 3138 3139 /** 3140 @override 3141 */ 3142 3143 }, { 3144 key: 'reset', 3145 value: function reset() { 3146 if (this.currentMask) this.currentMask.reset(); 3147 this.compiledMasks.forEach(function (cm) { 3148 return cm.reset(); 3149 }); 3150 } 3151 3152 /** 3153 @override 3154 */ 3155 3156 }, { 3157 key: 'remove', 3158 3159 3160 /** 3161 @override 3162 */ 3163 value: function remove() { 3164 var details = new ChangeDetails(); 3165 if (this.currentMask) { 3166 var _currentMask2; 3167 3168 details.aggregate((_currentMask2 = this.currentMask).remove.apply(_currentMask2, arguments)) 3169 // update with dispatch 3170 .aggregate(this._applyDispatch()); 3171 } 3172 3173 return details; 3174 } 3175 3176 /** 3177 @override 3178 */ 3179 3180 }, { 3181 key: 'extractInput', 3182 value: function extractInput() { 3183 var _currentMask3; 3184 3185 return this.currentMask ? (_currentMask3 = this.currentMask).extractInput.apply(_currentMask3, arguments) : ''; 3186 } 3187 3188 /** 3189 @override 3190 */ 3191 3192 }, { 3193 key: '_extractTail', 3194 value: function _extractTail() { 3195 var _currentMask4, _babelHelpers$get; 3196 3197 for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { 3198 args[_key3] = arguments[_key3]; 3199 } 3200 3201 return this.currentMask ? (_currentMask4 = this.currentMask)._extractTail.apply(_currentMask4, toConsumableArray(args)) : (_babelHelpers$get = get(MaskedDynamic.prototype.__proto__ || Object.getPrototypeOf(MaskedDynamic.prototype), '_extractTail', this)).call.apply(_babelHelpers$get, [this].concat(toConsumableArray(args))); 3202 } 3203 3204 /** 3205 @override 3206 */ 3207 3208 }, { 3209 key: '_appendTail', 3210 value: function _appendTail(tail) { 3211 var details = new ChangeDetails(); 3212 if (tail) details.aggregate(this._applyDispatch(tail.value)); 3213 3214 return details.aggregate(this.currentMask ? this.currentMask._appendTail(tail) : get(MaskedDynamic.prototype.__proto__ || Object.getPrototypeOf(MaskedDynamic.prototype), '_appendTail', this).call(this, tail)); 3215 } 3216 3217 /** 3218 @override 3219 */ 3220 3221 }, { 3222 key: 'doCommit', 3223 value: function doCommit() { 3224 if (this.currentMask) this.currentMask.doCommit(); 3225 get(MaskedDynamic.prototype.__proto__ || Object.getPrototypeOf(MaskedDynamic.prototype), 'doCommit', this).call(this); 3226 } 3227 3228 /** 3229 @override 3230 */ 3231 3232 }, { 3233 key: 'nearestInputPos', 3234 value: function nearestInputPos() { 3235 var _currentMask5, _babelHelpers$get2; 3236 3237 for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
3238 args[_key4] = arguments[_key4]; 3239 } 3240 3241 return this.currentMask ? (_currentMask5 = this.currentMask).nearestInputPos.apply(_currentMask5, toConsumableArray(args)) : (_babelHelpers$get2 = get(MaskedDynamic.prototype.__proto__ || Object.getPrototypeOf(MaskedDynamic.prototype), 'nearestInputPos', this)).call.apply(_babelHelpers$get2, [this].concat(toConsumableArray(args))); 3242 } 3243 }, { 3244 key: 'value', 3245 get: function get$$1() { 3246 return this.currentMask ? this.currentMask.value : ''; 3247 }, 3248 set: function set$$1(value) { 3249 set(MaskedDynamic.prototype.__proto__ || Object.getPrototypeOf(MaskedDynamic.prototype), 'value', value, this); 3250 } 3251 3252 /** 3253 @override 3254 */ 3255 3256 }, { 3257 key: 'unmaskedValue', 3258 get: function get$$1() { 3259 return this.currentMask ? this.currentMask.unmaskedValue : ''; 3260 }, 3261 set: function set$$1(unmaskedValue) { 3262 set(MaskedDynamic.prototype.__proto__ || Object.getPrototypeOf(MaskedDynamic.prototype), 'unmaskedValue', unmaskedValue, this); 3263 } 3264 3265 /** 3266 @override 3267 */ 3268 3269 }, { 3270 key: 'isComplete', 3271 get: function get$$1() { 3272 return !!this.currentMask && this.currentMask.isComplete; 3273 } 3274 }]); 3275 return MaskedDynamic; 3276}(Masked); 3277 3278MaskedDynamic.DEFAULTS = { 3279 dispatch: function dispatch(appended, masked, flags) { 3280 if (!masked.compiledMasks.length) return; 3281 3282 var inputValue = masked.rawInputValue; 3283 3284 // simulate input 3285 var inputs = masked.compiledMasks.map(function (cm, index) { 3286 var m = cm.clone(); 3287 m.rawInputValue = inputValue; 3288 m._append(appended, flags); 3289 3290 return { value: m.rawInputValue.length, index: index }; 3291 }); 3292 3293 // pop masks with longer values first 3294 inputs.sort(function (i1, i2) { 3295 return i2.value - i1.value; 3296 }); 3297 3298 return masked.compiledMasks[inputs[0].index]; 3299 } 3300}; 3301 3302/** 3303 * Applies mask on element. 3304 * @constructor 3305 * @param {HTMLInput|UIElement} el - Element to apply mask 3306 * @param {Object} opts - Custom mask options 3307 * @return {InputMask} 3308 */ 3309function IMask(el) { 3310 var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 3311 3312 // currently available only for input-like elements 3313 return new InputMask(el, opts); 3314} 3315 3316/** {@link InputMask} */ 3317IMask.InputMask = InputMask; 3318 3319/** {@link Masked} */ 3320IMask.Masked = Masked; 3321/** {@link MaskedPattern} */ 3322IMask.MaskedPattern = MaskedPattern; 3323/** {@link MaskedNumber} */ 3324IMask.MaskedNumber = MaskedNumber; 3325/** {@link MaskedDate} */ 3326IMask.MaskedDate = MaskedDate; 3327/** {@link MaskedRegExp} */ 3328IMask.MaskedRegExp = MaskedRegExp; 3329/** {@link MaskedFunction} */ 3330IMask.MaskedFunction = MaskedFunction; 3331/** {@link MaskedDynamic} */ 3332IMask.MaskedDynamic = MaskedDynamic; 3333/** {@link createMask} */ 3334IMask.createMask = createMask; 3335 3336g.IMask = IMask; 3337 3338return IMask; 3339 3340}))); 3341//# sourceMappingURL=imask.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.