1;(function() 2{ 3 if (BX.MaskedInput) 4 return; 5 6 var defaultDefinitions = { 7 "cypher": { 8 "char": "9", 9 "rule": "[0-9]" 10 }, 11 "hexrgb": { 12 "char": "h", 13 "rule": "[A-Fa-f0-9]" 14 }, 15 "lang_en": { 16 "char": "a", 17 "rule": "[a-zA-Z]" 18 } 19 }; 20 21 /** 22 * @param {object} params 23 * @constructor 24 */ 25 BX.MaskedInput = function (params) 26 { 27 this.mask = params.mask || ''; 28 this.placeholder = (params.placeholder || '_').substring(0, 1); 29 this.definitions = this.prepareDefinitions(params.definitions || ['cypher', 'lang_en']); 30 this.stopChangeEvent = false; 31 32 this.initInput(params); 33 }; 34 35 BX.MaskedInput.prototype.initInput = function (params) 36 { 37 if (params.input.tagName == 'INPUT') 38 { 39 this.input = new BX.MaskedInputElement({node: params.input}); 40 } 41 else 42 { 43 this.input = new BX.MaskedTextElement({node: params.input}); 44 } 45 46 this.dataInput = params.dataInput || null; 47 this.isDataInputClean = params.isDataInputClean || false; 48 this.isHoldOverInputValueInit = params.isHoldOverInputValueInit || false; 49 this.enableCheckingValue = params.enableCheckingValue || false; 50 this.onDataInputChange = params.onDataInputChange || null; 51 this.onDataInputInitValue = params.onDataInputInitValue || null; 52 53 BX.addCustomEvent(this.input, 'change', BX.proxy(this.onInputChange, this)); 54 BX.addCustomEvent(this.input, 'paste', BX.proxy(this.onInputPaste, this)); 55 BX.addCustomEvent(this.input, 'delete', BX.proxy(this.onInputDelete, this)); 56 57 BX.bind(this.input.node, 'focus', BX.proxy(function () 58 { 59 if (this.getFirstEmptyPosition() === null) 60 { 61 return; 62 } 63 64 setTimeout(BX.proxy(function () 65 { 66 this.moveCaret(this.getFirstEmptyPosition()); 67 }, this), 50); 68 }, this)); 69 70 if (!this.isHoldOverInputValueInit && !this.test(this.input.val())) 71 { 72 this.input.val(this.getMaskedPlaceholder()); 73 } 74 75 if (this.dataInput) 76 { 77 var dataInputVal = this.dataInput.value; 78 if (BX.type.isFunction(this.onDataInputInitValue)) 79 { 80 dataInputVal = this.onDataInputInitValue.apply(this, [dataInputVal]); 81 } 82 if (BX.type.isString(dataInputVal) && dataInputVal.length > 0) 83 { 84 this.setValue(dataInputVal); 85 } 86 87 BX.addCustomEvent(this, 'change', BX.proxy(function () 88 { 89 var inputVal = ''; 90 if (BX.type.isFunction(this.onDataInputChange)) 91 { 92 inputVal = this.onDataInputChange.apply(this, [this.getValueClean(), this.getValue()]); 93 } 94 else if (this.isDataInputClean) 95 { 96 inputVal = this.getValueClean(); 97 } 98 else 99 { 100 inputVal = this.getValue(); 101 } 102 103 if (!BX.type.isString(inputVal)) 104 { 105 inputVal = ''; 106 } 107 108 if (this.enableCheckingValue && !this.checkValue()) 109 { 110 inputVal = ''; 111 } 112 113 this.dataInput.value = inputVal; 114 115 }, this)); 116 117 } 118 }; 119 120 BX.MaskedInput.prototype.setMask = function (mask) 121 { 122 if (this.mask == mask) 123 { 124 return; 125 } 126 127 var val = this.getValueClean(); 128 this.mask = mask; 129 130 this.setChangeEventFiring(false); 131 this.setValue(val); 132 this.setChangeEventFiring(true); 133 }; 134 135 BX.MaskedInput.prototype.getMask = function () 136 { 137 return this.mask; 138 }; 139 140 BX.MaskedInput.prototype.setValue = function (val) 141 { 142 if (!this.mask) 143 { 144 this.input.val(val); 145 this.fireChangeEvent(); 146 return; 147 } 148 149 var lastCaretPosition = this.input.getSelectionStart(); 150 this.moveCaret(0); 151 152 this.input.val(this.mask); 153 154 var j = 0; 155 for (var i = 0; i < this.mask.length; i++) 156 { 157 if (!this.isMaskCharReplaceable(i)) 158 { 159 this.replaceChar(i, this.mask.charAt(i)); 160 continue; 161 } 162 163 while (true) 164 { 165 var char = val.charAt(j); 166 if (!char) 167 { 168 char = this.placeholder; 169 break; 170 } 171 172 if (char == this.placeholder) 173 { 174 break; 175 } 176 177 if (this.testChar(i, char)) 178 { 179 break; 180 } 181 182 j++; 183 } 184 185 this.replaceChar(i, char); 186 j++; 187 } 188 189 this.moveCaret(lastCaretPosition); 190 //this.moveCaret(this.getFirstEmptyPosition()); 191 this.fireChangeEvent(); 192 }; 193 194 BX.MaskedInput.prototype.getValue = function () 195 { 196 return this.input.val(); 197 }; 198 199 BX.MaskedInput.prototype.getFirstEmptyPosition = function () 200 { 201 var val = this.getValue(); 202 for (var i = 0; i < val.length; i++) 203 { 204 if (!this.isMaskCharReplaceable(i)) 205 { 206 continue; 207 } 208 209 var char = val.charAt(i); 210 if (char == this.placeholder) 211 { 212 return i; 213 } 214 } 215 216 return null; 217 }; 218 219 BX.MaskedInput.prototype.getValueClean = function () 220 { 221 var returnValue = ''; 222 var val = this.getValue(); 223 if (!this.mask) 224 { 225 return val; 226 } 227 228 for (var i = 0; i < val.length; i++) 229 { 230 if (!this.isMaskCharReplaceable(i)) 231 { 232 continue; 233 } 234 235 var char = val.charAt(i); 236 returnValue += char == this.placeholder ? '' : char; 237 } 238 239 return returnValue; 240 }; 241 242 BX.MaskedInput.prototype.checkValue = function () 243 { 244 var val = this.getValue(); 245 if (!this.mask) 246 { 247 return val; 248 } 249 250 for (var i = 0; i < val.length; i++) 251 { 252 if (!this.isMaskCharReplaceable(i)) 253 { 254 continue; 255 } 256 257 if (val.charAt(i) == this.placeholder) 258 { 259 return false;
260 } 261 } 262 263 return true; 264 }; 265 266 BX.MaskedInput.prototype.onInputDelete = function (directionLeft) 267 { 268 if (this.deleteSelection()) 269 { 270 this.fireChangeEvent(); 271 return; 272 } 273 274 var pos = this.input.getSelectionStart(); 275 if (directionLeft) 276 { 277 if (pos === this.mask.length) 278 { 279 this.replaceChar(pos - 1, this.placeholder); 280 } 281 else 282 { 283 this.shift(pos, pos - 1); 284 } 285 this.moveCaret(pos - 1); 286 } 287 else 288 { 289 if (pos === this.mask.length - 1) 290 { 291 this.replaceChar(pos, this.placeholder); 292 } 293 else if (pos < this.mask.length - 1) 294 { 295 this.shift(pos + 1, pos); 296 } 297 298 this.moveCaret(pos); 299 } 300 this.fireChangeEvent(); 301 }; 302 303 BX.MaskedInput.prototype.onInputPaste = function (pastedData) 304 { 305 this.deleteSelection(); 306 for (var i = 0; i < pastedData.length; i++) 307 { 308 this.setCharOnCaret(pastedData.charAt(i)); 309 } 310 this.fireChangeEvent(); 311 }; 312 313 BX.MaskedInput.prototype.onInputChange = function (char) 314 { 315 if (this.input.val() == '' && this.mask) 316 { 317 this.input.val(this.getMaskedPlaceholder()); 318 this.input.setCaretPosition(0); 319 } 320 321 this.deleteSelection(); 322 this.setCharOnCaret(char); 323 this.fireChangeEvent(); 324 }; 325 326 BX.MaskedInput.prototype.moveCaret = function (pos) 327 { 328 if (pos > this.mask.length) 329 { 330 pos = this.mask.length; 331 } 332 else if (pos < 0) 333 { 334 pos = 0; 335 } 336 else if (pos === null) 337 { 338 return this.input.getSelectionStart(); 339 } 340 341 this.input.setCaretPosition(pos); 342 return pos; 343 }; 344 345 BX.MaskedInput.prototype.findClosestAllowPosition = function (pos, char, directionLeft) 346 { 347 if (typeof pos === 'undefined') 348 { 349 pos = 0; 350 } 351 if (typeof char === 'undefined') 352 { 353 char = null; 354 } 355 if (typeof directionLeft === 'undefined') 356 { 357 directionLeft = false; 358 } 359 360 while (true) 361 { 362 if (!directionLeft && pos >= this.mask.length) 363 { 364 return null; 365 } 366 else if (directionLeft && pos <= 0) 367 { 368 return 0; 369 } 370 371 if (this.isMaskCharReplaceable(pos)) 372 { 373 break; 374 } 375 376 if (!directionLeft) 377 { 378 pos++; 379 } 380 else 381 { 382 pos--; 383 } 384 } 385 386 if (!this.isMaskCharReplaceable(pos)) 387 { 388 return null; 389 } 390 if (char && !this.testChar(pos, char)) 391 { 392 return null; 393 } 394 395 return pos; 396 }; 397 398 BX.MaskedInput.prototype.setCharOnCaret = function (char) 399 { 400 var pos = this.input.getSelectionStart(); 401 pos = this.findClosestAllowPosition(pos, char); 402 if (pos === null) 403 { 404 return; 405 } 406 407 this.shift(pos, pos + 1); 408 pos = this.replaceChar(pos, char); 409 410 if (pos === null) 411 { 412 return; 413 } 414 415 pos = this.findClosestAllowPosition(pos + 1); 416 417 this.moveCaret(pos); 418 419 if (BX.browser.IsAndroid() && BX.browser.DetectAndroidVersion() < 7) 420 { 421 var _this = this; 422 setTimeout(function () 423 { 424 _this.moveCaret(pos); 425 }, 50); 426 } 427 428 /* 429 var pos = this.getFirstEmptyPosition(); 430 if(pos) 431 { 432 this.moveCaret(pos); 433 } 434 */ 435 }; 436 437 BX.MaskedInput.prototype.shift = function (start, target) 438 { 439 var i, char = null; 440 var buffer = []; 441 442 for (i = start; i < this.mask.length; i++) 443 { 444 if (!this.isMaskCharReplaceable(i)) continue; 445 var val = this.input.val(); 446 buffer.push(val.charAt(i)); 447 this.replaceChar(i, this.placeholder); 448 } 449 450 buffer.reverse(); 451 for (i = target; i < this.mask.length; i++) 452 { 453 if (!this.isMaskCharReplaceable(i)) continue; 454 if (buffer.length > 0) 455 { 456 char = buffer.pop(); 457 } 458 else 459 { 460 char = this.placeholder; 461 } 462 463 this.replaceChar(i, char); 464 } 465 }; 466 467 BX.MaskedInput.prototype.deleteSelection = function () 468 { 469 var posStart = this.input.getSelectionStart(); 470 var posEnd = this.input.getSelectionEnd(); 471 if (posStart == posEnd) 472 { 473 return false; 474 } 475 476 // delete 477 for (var i = posStart; i < posEnd; i++) 478 { 479 if (!this.isMaskCharReplaceable(i)) 480 { 481 continue; 482 } 483 484 this.replaceChar(i, this.placeholder); 485 } 486 487 this.shift(posEnd, posStart); 488 this.moveCaret(posStart); 489 490 return true; 491 }; 492 493 BX.MaskedInput.prototype.setChangeEventFiring = function (start) 494 { 495 this.stopChangeEvent = !start; 496 }; 497 498 BX.MaskedInput.prototype.fireChangeEvent = function () 499 { 500 if (!this.stopChangeEvent) 501 { 502 BX.onCustomEvent(this, 'change', [this.getValueClean(), this.getValue()]); 503 } 504 }; 505 506 BX.MaskedInput.prototype.replaceChar = function (pos, char) 507 { 508 if (isNaN(pos)) 509 { 510 return null; 511 } 512 513 var val = this.input.val(); 514 var valTml = val.substring(0, pos) + char; 515 valTml += (pos >= val.length) ? '' : val.substring((pos + 1)); 516 val = valTml; 517 518 this.input.val(val); 519 520 return pos; 521 }; 522 BX.MaskedInput.prototype.isMaskCharReplaceable = function (pos) 523 { 524 var char = this.mask.charAt(pos); 525 if (!char) 526 { 527 return false;
528 } 529 530 return !!this.definitions[char]; 531 }; 532 533 BX.MaskedInput.prototype.getMaskedPlaceholder = function () 534 { 535 var val = ''; 536 for (var i = 0; i < this.mask.length; i++) 537 { 538 var char = this.mask[i]; 539 if (this.definitions[char]) 540 { 541 char = this.placeholder; 542 } 543 544 val += char; 545 } 546 547 return val; 548 }; 549 550 BX.MaskedInput.prototype.prepareDefinitions = function (definitions) 551 { 552 var result = {}; 553 554 definitions.forEach(function (definition) 555 { 556 if (BX.type.isString(definition) && defaultDefinitions[definition]) 557 { 558 definition = defaultDefinitions[definition]; 559 } 560 561 if (BX.type.isPlainObject(definition)) 562 { 563 var def = { 564 "rule": definition.rule, 565 "isFunction": false 566 }; 567 if (BX.type.isFunction(definition.rule)) 568 { 569 def.isFunction = true; 570 } 571 else 572 { 573 def.regexp = new RegExp(definition.rule); 574 } 575 576 result[definition.char] = def; 577 } 578 }, this); 579 return result; 580 }; 581 582 BX.MaskedInput.prototype.test = function (string) 583 { 584 for (var i = 0; i < string.length; i++) 585 { 586 var r = this.testChar(i, string[i]); 587 if (!r) 588 { 589 return false; 590 } 591 } 592 593 return true; 594 }; 595 596 BX.MaskedInput.prototype.testChar = function (pos, char) 597 { 598 var maskChar = this.mask[pos]; 599 600 if (!this.definitions[maskChar]) 601 { 602 return char === maskChar; 603 } 604 605 var isSuccess = true; 606 if (this.definitions[maskChar].isFunction) 607 { 608 isSuccess = !!this.definitions[maskChar].func.apply(this, [char]); 609 } 610 else 611 { 612 isSuccess = this.definitions[maskChar].regexp.test(char); 613 } 614 615 return isSuccess; 616 }; 617 618 BX.MaskedInputElement = function (params) 619 { 620 this.node = params.node; 621 this.skipTextInputEvent = false; 622 623 BX.bind(this.node, 'paste', BX.proxy(this.onChange, this)); 624 BX.bind(this.node, 'keypress', BX.proxy(this.onChange, this)); 625 626 if (BX.browser.IsAndroid() && BX.browser.DetectAndroidVersion() < 7) 627 { 628 BX.bind(this.node, 'textInput', BX.proxy(this.onAndroidInput, this)); 629 BX.bind(this.node, 'keydown', BX.proxy(this.onAndroidInput, this)); 630 } 631 else 632 { 633 BX.bind(this.node, 'keydown', BX.proxy(this.onChange, this)); 634 } 635 }; 636 637 BX.MaskedInputElement.prototype.val = function (value) 638 { 639 if (typeof value != 'undefined') 640 { 641 this.node.value = value; 642 } 643 644 return this.node.value; 645 }; 646 647 BX.MaskedInputElement.prototype.onAndroidInput = function (e) 648 { 649 var kc = 0; 650 if (e.type == 'keydown') 651 { 652 kc = (typeof e.which == "number") ? e.which : e.keyCode; 653 if (kc != 8) 654 { 655 if (e.key == "Unidentified") // if keydown has wrong key, use textInput with right key 656 { 657 this.skipTextInputEvent = false; 658 BX.PreventDefault(e); 659 return false; 660 } 661 else 662 { 663 this.skipTextInputEvent = true; 664 } 665 } 666 } 667 else 668 { 669 if (this.skipTextInputEvent) 670 { 671 BX.PreventDefault(e); 672 return false; 673 } 674 675 kc = e.data.toUpperCase().charCodeAt(0); 676 } 677 678 var eventObject = { 679 keyCode: kc, 680 which: kc, 681 type: 'keydown' 682 }; 683 684 return this.onChange(eventObject, e); 685 }; 686 687 BX.MaskedInputElement.prototype.onChange = function (e, eReal) 688 { 689 var isCatch = true; 690 var kc = (typeof e.which == "number") ? e.which : e.keyCode; 691 692 if (kc <= 0) 693 { 694 return; 695 } 696 697 switch (e.type) 698 { 699 case 'keydown': 700 701 isCatch = ( 702 (!e.ctrlKey && !e.altKey && !e.metaKey) 703 && 704 ( 705 kc 706 && 707 ( 708 (kc > 46 && kc <= 90) // chars 709 || 710 kc > 145 711 || 712 kc === 13 // Carriage return 713 || 714 kc === 8 // [backspace] key 715 || 716 kc === 46 // [Del] key 717 || 718 (BX.browser.IsIOS() && kc === 127) // iOS [delete] key 719 ) 720 ) 721 ); 722 break; 723 case 'keypress': 724 break; 725 } 726 727 if (!isCatch) 728 { 729 return; 730 } 731 732 BX.PreventDefault(eReal || e); 733 if (e.type == 'paste') 734 { 735 var clipboardData = e.clipboardData || window.clipboardData; 736 var pastedData = clipboardData.getData('Text'); 737 BX.onCustomEvent(this, 'paste', [pastedData]); 738 } 739 else if (kc === 8 || kc === 46 || (BX.browser.IsIOS() && kc === 127)) 740 { 741 var directionLeft = kc === 8; 742 BX.onCustomEvent(this, 'delete', [directionLeft]); 743 } 744 else 745 { 746 var char = String.fromCharCode(kc); 747 BX.onCustomEvent(this, 'change', [char]); 748 } 749 }; 750 751 BX.MaskedInputElement.prototype.setCaretPosition = function (pos) 752 { 753 this.node.setSelectionRange(pos, pos); 754 }; 755 756 BX.MaskedInputElement.prototype.getSelectionStart = function () 757 { 758 if (this.node.selectionStart) 759 { 760 return this.node.selectionStart; 761 } 762 else if (this.node.createTextRange) 763 { 764 var range = this.node.createTextRange().duplicate(); 765 range.moveEnd('character', this.node.value.length); 766 if (range.text == '') 767 { 768 return this.node.value.length; 769 } 770 else 771 {
772 return this.node.value.lastIndexOf(range.text); 773 } 774 } 775 else 776 { 777 return 0; 778 } 779 }; 780 781 BX.MaskedInputElement.prototype.getSelectionEnd = function () 782 { 783 if (this.node.selectionEnd) 784 { 785 return this.node.selectionEnd; 786 } 787 else if (this.node.createTextRange) 788 { 789 var range = this.node.createTextRange().duplicate(); 790 range.moveStart('character', -this.node.value.length); 791 return range.text.length; 792 } 793 else 794 { 795 return 0; 796 } 797 }; 798 799 BX.MaskedTextElement = function (params) 800 { 801 this.node = params.node; 802 }; 803 804 805 BX.MaskedTextElement.prototype.val = function (value) 806 { 807 if (typeof value != 'undefined') 808 { 809 this.node.innerText = value; 810 } 811 812 return this.node.innerText; 813 }; 814 815 BX.MaskedTextElement.prototype.onChange = function (e) 816 { 817 }; 818 819 BX.MaskedTextElement.prototype.setCaretPosition = function (pos) 820 { 821 }; 822 823 BX.MaskedTextElement.prototype.getSelectionStart = function () 824 { 825 return 0; 826 }; 827 828 BX.MaskedTextElement.prototype.getSelectionEnd = function () 829 { 830 return 0; 831 }; 832})();
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.