1/** 2 * jquery.meio.mask.js 3 * @author: fabiomcosta 4 * @version: 1.1.14 5 * @help: https://github.com/fabiomcosta/jquery-meiomask/wiki 6 * 7 * Created by Fabio M. Costa on 2008-09-16. Please report any bug at http://www.meiocodigo.com 8 * 9 * Copyright (c) 2008 Fabio M. Costa http://www.meiocodigo.com 10 * 11 * The MIT License (http://www.opensource.org/licenses/mit-license.php) 12 * 13 * Permission is hereby granted, free of charge, to any person 14 * obtaining a copy of this software and associated documentation 15 * files (the "Software"), to deal in the Software without 16 * restriction, including without limitation the rights to use, 17 * copy, modify, merge, publish, distribute, sublicense, and/or sell 18 * copies of the Software, and to permit persons to whom the 19 * Software is furnished to do so, subject to the following 20 * conditions: 21 * 22 * The above copyright notice and this permission notice shall be 23 * included in all copies or substantial portions of the Software. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 27 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 29 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 30 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 31 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 32 * OTHER DEALINGS IN THE SOFTWARE. 33 */ 34 35/** 36 * //FixIn: 8.7.9.11 37 * 38 * replaced here .browser to .browser_is_supported_meio 39 */ 40 41(function($) { 42 43 // https://github.com/jquery/jquery-migrate/blob/master/src/core.js#L50 44 if (!$.browser_is_supported_meio) { 45 var uaMatch = function(ua) { 46 ua = ua.toLowerCase(); 47 48 var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || /(msie) ([\w.]+)/.exec(ua) || ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; 49 50 return match[2] || '0'; 51 }; 52 53 $.browser_is_supported_meio = { 54 mozilla: /mozilla/.test(navigator.userAgent.toLowerCase()) && !/webkit/.test(navigator.userAgent.toLowerCase()), 55 webkit: /webkit/.test(navigator.userAgent.toLowerCase()), 56 opera: /opera/.test(navigator.userAgent.toLowerCase()), 57 msie: /msie/.test(navigator.userAgent.toLowerCase()), 58 android: (navigator.userAgent.toLowerCase().indexOf('mozilla/5.0') > -1 && navigator.userAgent.toLowerCase().indexOf('android ') > -1 && navigator.userAgent.toLowerCase().indexOf('applewebkit') > -1), 59 version: uaMatch(navigator.userAgent) 60 }; 61 } 62 63 var isMobile = (window.orientation != null); 64 65 // browsers like firefox2 and before and opera doesnt have the onPaste event, but the paste feature can be done with the onInput event. 66 var pasteEvent = (($.browser_is_supported_meio.opera || ($.browser_is_supported_meio.mozilla && parseFloat($.browser_is_supported_meio.version.substr(0, 3)) < 1.9)) ? 'input' : 'paste'); 67 68 // the timeout is set because we can't get the value from the input without it 69 var pasteHandler = function(e) { 70 e = $.event.fix(e || window.event); 71 e.type = 'paste'; 72 var el = e.target; 73 74 setTimeout(function() { 75 $.event.dispatch.call(el, e); 76 }, 1); 77 }; 78 79 $.event.special.paste = { 80 setup: function() { 81 if (this.addEventListener) this.addEventListener(pasteEvent, pasteHandler, false); 82 else if (this.attachEvent) this.attachEvent('on' + pasteEvent, pasteHandler); 83 }, 84 85 teardown: function() { 86 if (this.removeEventListener) this.removeEventListener(pasteEvent, pasteHandler, false); 87 else if (this.detachEvent) this.detachEvent('on' + pasteEvent, pasteHandler); 88 } 89 }; 90 91 $.extend({ 92 mask: { 93 94 // the mask rules. You may add yours! 95 // number rules will be overwritten 96 rules: { 97 'z': /[a-z]/, 98 'Z': /[A-Z]/, 99 'a': /[a-zA-Z]/, 100 '*': /[0-9a-zA-Z]/, 101 '@': /[0-9a-zA-ZçÃáà ãâéèêÃìóòôõúùü]/ 102 }, 103 104 // these keys will be ignored by the mask. 105 // all these numbers where obtained on the keydown event 106 keyRepresentation: { 107 8: 'backspace', 108 9: 'tab', 109 13: 'enter', 110 16: 'shift', 111 17: 'control', 112 18: 'alt', 113 27: 'esc', 114 33: 'page up', 115 34: 'page down', 116 35: 'end', 117 36: 'home', 118 37: 'left', 119 38: 'up', 120 39: 'right', 121 40: 'down', 122 45: 'insert', 123 46: 'delete', 124 116: 'f5', 125 123: 'f12', 126 224: 'command' 127 }, 128 129 signals: { 130 '+': '',
131 '-': '-' 132 }, 133 134 // default settings for the plugin 135 options: { 136 attr: 'alt', // an attr to look for the mask name or the mask itself 137 mask: null, // the mask to be used on the input 138 type: 'fixed', // the mask of this mask 139 maxLength: -1, // the maxLength of the mask 140 defaultValue: '', // the default value for this input 141 signal: false, // this should not be set, to use signal at masks put the signal you want ('-' or '+') at the default value of this mask. 142 // See the defined masks for a better understanding. 143 144 textAlign: true, // use false to not use text-align on any mask (at least not by the plugin, you may apply it using css) 145 selectCharsOnFocus: true, // select all chars from input on its focus 146 autoTab: true, // auto focus the next form element when you type the mask completely 147 setSize: false, // sets the input size based on the length of the mask (work with fixed and reverse masks only) 148 fixedChars: '[(),.:/ -]', // fixed chars to be used on the masks. You may change it for your needs! 149 150 onInvalid: function() {}, 151 onValid: function() {}, 152 onOverflow: function() {}, 153 onFocus: function(input, evt) {}, 154 onBlur: function(input, evt) {} 155 }, 156 157 // masks. You may add yours! 158 // Ex: $.fn.setMask.masks.msk = {mask: '999'} 159 // and then if the 'attr' options value is 'alt', your input should look like: 160 // <input type="text" name="some_name" id="some_name" alt="msk" /> 161 masks: { 162 'phone': { 163 mask: '(99) 9999-9999' 164 }, 165 'phone-us': { 166 mask: '(999) 999-9999' 167 }, 168 'cpf': { 169 mask: '999.999.999-99' 170 }, // cadastro nacional de pessoa fisica (kind of a brazillian ssn) 171 'cnpj': { 172 mask: '99.999.999/9999-99' 173 }, 174 'date': { 175 mask: '39/19/9999' 176 }, // uk date 177 'date-us': { 178 mask: '19/39/9999' 179 }, 180 'cep': { 181 mask: '99999-999' 182 }, 183 'time': { 184 mask: '29:59' 185 }, 186 'cc': { 187 mask: '9999 9999 9999 9999' 188 }, // credit card 189 'integer': { 190 mask: '999.999.999.999', 191 type: 'reverse' 192 }, 193 'decimal': { 194 mask: '99,999.999.999.999', 195 type: 'reverse', 196 defaultValue: '000' 197 }, 198 'decimal-us': { 199 mask: '99.999,999,999,999', 200 type: 'reverse', 201 defaultValue: '000' 202 }, 203 'signed-decimal': { 204 mask: '99,999.999.999.999', 205 type: 'reverse', 206 defaultValue: '+000' 207 }, 208 'signed-decimal-us': { 209 mask: '99,999.999.999.999', 210 type: 'reverse', 211 defaultValue: '+000' 212 } 213 }, 214 215 init: function() { 216 // if has not inited... 217 if (!this.hasInit) { 218 219 var self = this, 220 i, 221 keyRep = this.keyRepresentation; 222 223 this.ignore = false; 224 225 // constructs number rules 226 for (i = 0; i <= 9; i++) this.rules[i] = new RegExp('[0-' + i + ']'); 227 228 this.keyRep = keyRep; 229 // ignore keys array creation for iphone or the normal ones 230 this.ignoreKeys = []; 231 $.each(keyRep, function(key) { 232 self.ignoreKeys.push(parseInt(key, 10)); 233 }); 234 235 this.hasInit = true; 236 } 237 }, 238 239 set: function(el, options) { 240 241 var maskObj = this, 242 $el = $(el), 243 mlStr = 'maxLength'; 244 245 options = options || {}; 246 this.init(); 247 248 return $el.each(function() { 249 250 if (options.attr) maskObj.options.attr = options.attr; 251 252 var $this = $(this), 253 o = $.extend({}, maskObj.options), 254 attrValue = $this.attr(o.attr), 255 tmpMask = ''; 256 257 // then we look for the 'attr' option 258 tmpMask = (typeof options == 'string') ? options : (attrValue !== '') ? attrValue : null; 259 if (tmpMask) o.mask = tmpMask; 260 261 // then we see if it's a defined mask 262 if (maskObj.masks[tmpMask]) o = $.extend(o, maskObj.masks[tmpMask]); 263 264 // then it looks if the options is an object, if it is
264we will overwrite the actual options 265 if (typeof options == 'object' && options.constructor != Array) o = $.extend(o, options); 266 267 //then we look for some metadata on the input 268 if ($.metadata) o = $.extend(o, $this.metadata()); 269 270 if (o.mask != null) { 271 272 // prevents javascript automatic type convertion 273 o.mask += ''; 274 275 if ($this.data('mask')) maskObj.unset($this); 276 277 var defaultValue = o.defaultValue, 278 reverse = (o.type === 'reverse'), 279 fixedCharsRegG = new RegExp(o.fixedChars, 'g'); 280 281 if (o.maxLength === -1) o.maxLength = $this.attr(mlStr); 282 283 o = $.extend({}, o, { 284 fixedCharsReg: new RegExp(o.fixedChars), 285 fixedCharsRegG: fixedCharsRegG, 286 maskArray: o.mask.split(''), 287 maskNonFixedCharsArray: o.mask.replace(fixedCharsRegG, '').split('') 288 }); 289 290 // setSize option (this is kept when the mask is removed) 291 if ((o.type == 'fixed' || reverse) && o.setSize && !$this.attr('size')) $this.attr('size', o.mask.length); 292 293 // sets text-align right for reverse masks 294 if (reverse && o.textAlign) $this.css('text-align', 'right'); 295 296 if (this.value !== '' || defaultValue !== '') { 297 // apply mask to the current value of the input or to the default value 298 var val = maskObj.string((this.value !== '') ? this.value : defaultValue, o); 299 //setting defaultValue fixes the reset button from the form 300 this.defaultValue = val; 301 $this.val(val); 302 } 303 304 // compatibility patch for infinite mask, that is now repeat 305 if (o.type == 'infinite') o.type = 'repeat'; 306 307 $this.data('mask', o); 308 309 // removes the maxLength attribute (it will be set again if you use the unset method) 310 $this.removeAttr(mlStr); 311 312 // setting the input events 313 $this.on('keydown.mask', { 314 func: maskObj._onKeyDown, 315 thisObj: maskObj 316 }, maskObj._onMask) 317 .on('keypress.mask', { 318 func: maskObj._onKeyPress, 319 thisObj: maskObj 320 }, maskObj._onMask) 321 .on('keyup.mask', { 322 func: maskObj._onKeyUp, 323 thisObj: maskObj 324 }, maskObj._onMask) 325 .on('paste.mask', { 326 func: maskObj._onPaste, 327 thisObj: maskObj 328 }, maskObj._onMask) 329 .on('drop.mask', { 330 func: maskObj._onPaste, 331 thisObj: maskObj 332 }, maskObj._onMask) 333 .on('focus.mask', maskObj._onFocus) 334 .on('blur.mask', maskObj._onBlur) 335 .on('change.mask', maskObj._onChange); 336 } 337 }); 338 }, 339 340 //unsets the mask from el 341 unset: function(el) { 342 var $el = $(el); 343 344 return $el.each(function() { 345 var $this = $(this); 346 if ($this.data('mask')) { 347 var maxLength = $this.data('mask').maxLength; 348 if (maxLength != -1) $this.attr('maxLength', maxLength); 349 $this.unbind('.mask') 350 .removeData('mask'); 351 } 352 }); 353 }, 354 355 //masks a string
356 string: function(str, options) { 357 this.init(); 358 var o = {}; 359 if (typeof str != 'string') str = String(str); 360 switch (typeof options) { 361 case 'string': 362 // then we see if it's a defined mask 363 if (this.masks[options]) o = $.extend(o, this.masks[options]); 364 else o.mask = options; 365 break; 366 case 'object': 367 o = options; 368 } 369 if (!o.fixedChars) o.fixedChars = this.options.fixedChars; 370 371 var fixedCharsReg = new RegExp(o.fixedChars), 372 fixedCharsRegG = new RegExp(o.fixedChars, 'g'); 373 374 // insert signal if any 375 if ((o.type === 'reverse') && o.defaultValue) { 376 if (typeof this.signals[o.defaultValue.charAt(0)] != 'undefined') { 377 var maybeASignal = str.charAt(0); 378 o.signal = (typeof this.signals[maybeASignal] != 'undefined') ? this.signals[maybeASignal] : this.signals[o.defaultValue.charAt(0)]; 379 o.defaultValue = o.defaultValue.substring(1); 380 } 381 } 382 383 return this.__maskArray(str.split(''), 384 o.mask.replace(fixedCharsRegG, '').split(''), 385 o.mask.split(''), 386 o.type, 387 o.maxLength, 388 o.defaultValue, 389 fixedCharsReg, 390 o.signal); 391 }, 392 393 // all the 3 events below are here just to fix the change event on reversed masks. 394 // It isn't fired in cases that the keypress event returns false (needed). 395 _onFocus: function(e) { 396 var $this = $(this), 397 dataObj = $this.data('mask'); 398 dataObj.inputFocusValue = $this.val(); 399 dataObj.changed = false; 400 if (dataObj.selectCharsOnFocus) $this.select(); 401 // trigger mask function 402 dataObj.onFocus(this, e); 403 }, 404 405 _onBlur: function(e) { 406 var $this = $(this), 407 dataObj = $this.data('mask'); 408 if (dataObj.inputFocusValue != $this.val() && !dataObj.changed) $this.trigger('change'); 409 // trigger mask function 410 dataObj.onBlur(this, e); 411 }, 412 413 _onChange: function(e) { 414 $(this).data('mask').changed = true; 415 }, 416 417 _onMask: function(e) { 418 var thisObj = e.data.thisObj, 419 o = {}; 420 421 o._this = e.target; 422 o.$this = $(o._this); 423 o.data = o.$this.data('mask'); 424 425 if (o.$this.attr('readonly') || !o.data) { 426 return true; 427 } 428 429 o[o.data.type] = true; 430 o.value = o.$this.val(); 431 o.nKey = thisObj.__getKeyNumber(e); 432 o.range = thisObj.__getRange(o._this); 433 o.valueArray = o.value.split(''); 434 return e.data.func.call(thisObj, e, o); 435 }, 436 437 _onKeyDown: function(e, o) { 438 // lets say keypress at desktop == keydown at iphone (theres no keypress at iphone) 439 this.ignore = $.inArray(o.nKey, this.ignoreKeys) > -1 || ((e.ctrlKey || e.metaKey || e.altKey) && e.key); 440 if (this.ignore) { 441 var rep = this.keyRep[o.nKey]; 442 o.data.onValid.call(o._this, rep || '', o.nKey); 443 } 444 return true; 445 }, 446 447 _onKeyUp: function(e, o) { 448 //9=TAB_KEY 16=SHIFT_KEY 449 //this is a little bug, when you go to an input with tab key 450 //it would remove the range selected by default, and that's not a desired behavior 451 if (o.nKey === 9 || o.nKey === 16) return true; 452 453 if (o.repeat) { 454 this.__autoTab(o); 455 return true; 456 } 457 458 return this._onPaste(e, o); 459 }, 460 461 _onPaste: function(e, o) { 462 // changes the signal at the data obj from the input 463 if (o.reverse) this.__changeSignal(e.type, o); 464 465 var $thisVal = this.__maskArray( 466 o.valueArray, 467 o.data.maskNonFixedCharsArray, 468 o.data.maskArray, 469 o.data.type, 470 o.data.maxLength,
471 o.data.defaultValue, 472 o.data.fixedCharsReg, 473 o.data.signal); 474 475 o.$this.val($thisVal); 476 // this makes the caret stay at first position when 477 // the user removes all values in an input and the plugin adds the default value to it (if it haves one). 478 if (!o.reverse && o.data.defaultValue.length && (o.range.start === o.range.end)) this.__setRange(o._this, o.range.start, o.range.end); 479 480 //fix so ie's and safari's caret won't go to the end of the input value. 481 if (($.browser_is_supported_meio.msie || $.browser_is_supported_meio.safari) && !o.reverse) this.__setRange(o._this, o.range.start, o.range.end); 482 483 if (this.ignore) return true; 484 485 this.__autoTab(o); 486 return true; 487 }, 488 489 _onKeyPress: function(e, o) { 490 491 if (this.ignore) return true; 492 493 // changes the signal at the data obj from the input 494 if (o.reverse) this.__changeSignal(e.type, o); 495 496 var c = String.fromCharCode(o.nKey), 497 rangeStart = o.range.start, 498 rawValue = o.value, 499 maskArray = o.data.maskArray; 500 501 if (o.reverse) { 502 // the input value from the range start to the value start 503 var valueStart = rawValue.substr(0, rangeStart), 504 // the input value from the range end to the value end 505 valueEnd = rawValue.substr(o.range.end, rawValue.length); 506 507 rawValue = valueStart + c + valueEnd; 508 //necessary, if not decremented you will be able to input just the mask.length-1 if signal!='' 509 //ex: mask:99,999.999.999 you will be able to input 99,999.999.99 510 if (o.data.signal && (rangeStart - o.data.signal.length > 0)) { 511 rangeStart -= o.data.signal.length; 512 } 513 } 514 515 var valueArray = rawValue.replace(o.data.fixedCharsRegG, '').split(''), 516 // searches for fixed chars begining from the range start position, till it finds a
516non fixed 517 extraPos = this.__extraPositionsTill(rangeStart, maskArray, o.data.fixedCharsReg); 518 519 o.rsEp = rangeStart + extraPos; 520 521 if (o.repeat) { 522 o.rsEp = 0; 523 } 524 525 // if the rule for this character doesnt exist (value.length is bigger than mask.length) 526 // added a verification for maxLength in the case of the repeat type mask 527 if (!this.rules[maskArray[o.rsEp]] || (o.data.maxLength != -1 && valueArray.length >= o.data.maxLength && o.repeat)) { 528 // auto focus on the next input of the current form 529 o.data.onOverflow.call(o._this, c, o.nKey); 530 return false; 531 } 532 533 // if the new character is not obeying the law... 534 else if (!this.rules[maskArray[o.rsEp]].test(c)) { 535 o.data.onInvalid.call(o._this, c, o.nKey); 536 return false; 537 } else { 538 o.data.onValid.call(o._this, c, o.nKey); 539 } 540 541 var $thisVal = this.__maskArray( 542 valueArray, 543 o.data.maskNonFixedCharsArray, 544 maskArray, 545 o.data.type, 546 o.data.maxLength, 547 o.data.defaultValue, 548 o.data.fixedCharsReg, 549 o.data.signal, 550 extraPos); 551 552 if (!o.repeat) { 553 o.$this.val($thisVal); 554 } 555 556 return (o.reverse) ? this._keyPressReverse(e, o) : (o.fixed) ? this._keyPressFixed(e, o) : true; 557 }, 558 559 _keyPressFixed: function(e, o) { 560 561 if (o.range.start == o.range.end) { 562 // the 0 thing is because theres an unwanted behavior when you put a default 563 // value on a fixed mask and you select the value from the input the range would go to the 564 // end of the string when you enter a char. with this it will overwrite the first char wich is a better behavior. 565 // opera fix, cant have range value bigger than value length, i think it loops thought the input value... 566 if ((o.rsEp === 0 && o.value.length === 0) || o.rsEp < o.value.length) this.__setRange(o._this, o.rsEp, o.rsEp + 1); 567 } else this.__setRange(o._this, o.range.start, o.range.end); 568 569 return true; 570 }, 571 572 _keyPressReverse: function(e, o) { 573 // fix for ie 574 // this bug was pointed by Pedro Martins 575 // it fixes a strange behavior that ie was having after a char was inputted in a text input that 576 // had its content selected by any range 577 if ($.browser_is_supported_meio.msie && ((o.range.start === 0 && o.range.end === 0) || o.range.start != o.range.end)) this.__setRange(o._this, o.value.length); 578 return false; 579 }, 580 581 __autoTab: function(o) { 582 if (o.data.autoTab && ( 583 ( 584 o.$this.val().length >= o.data.maskArray.length && !o.repeat) || ( 585 o.data.maxLength != -1 && o.valueArray.length >= o.data.maxLength && o.repeat))) { 586 var nextEl = this.__getNextInput(o._this, o.data.autoTab); 587 if (nextEl) { 588 o.$this.trigger('blur'); 589 nextEl.trigger( 'focus' ).trigger( 'select' ); //FixIn: 8.7.11.12 590 } 591 } 592 }, 593 594 // changes the signal at the data obj from the input 595 __changeSignal: function(eventType, o) { 596 if (o.data.signal !== false) { 597 var inputChar = (eventType === 'paste') ? o.value.charAt(0) : String.fromCharCode(o.nKey); 598 if (this.signals && (typeof this.signals[inputChar] !== 'undefined')) { 599 o.data.signal = this.signals[inputChar]; 600 } 601 } 602 }, 603 604 __getKeyNumber: function(e) { 605 return (e.charCode || e.keyCode || e.which); 606 }, 607 608 // this function is totaly specific to be used with this plugin, youll never need it 609 // it gets the array representing an unmasked string and masks it depending on the type of the mask 610 __maskArray: function(valueArray, maskNonFixedCharsArray, maskArray, type, maxlength, defaultValue, fixedCharsReg, signal, extraPos) { 611 if (type === 'reverse') valueArray.reverse(); 612 valueArray = this.__removeInvalidChars(valueArray, maskNonFixedCharsArray, type === 'repeat' || type === 'infinite'); 613 if (defaultValue) valueArray = this.__applyDefaultValue.call(valueArray, defaultValue); 614 valueArray = this.__applyMask(valueArray, maskArray, extraPos, fixedCharsReg); 615 switch (type) { 616 case 'reverse': 617 valueArray.reverse(); 618 return (signal || '') + valueArray.join('').substring(valueArray.length - maskArray.length); 619 case 'infinite': 620 case 'repeat': 621 var joinedValue = valueArray.join(''); 622 return (maxlength !== -1 && valueArray.length >= maxlength) ? joinedValue.substring(0, maxlength) : joinedValue; 623 default: 624 return valueArray.join('').substring(0, maskArray.length); 625 } 626 return ''; 627 }, 628 629 // applyes the default value to the result string 630 __applyDefaultValue: function(defaultValue) { 631 var defLen = defaultValue.length, 632 thisLen = this.length, 633 i; 634 //removes the leading chars 635 for (i = thisLen - 1; i >= 0; i--) { 636 if (this[i] == defaultValue.charAt(0)) { 637 this.pop(); 638 } else break; 639 } 640 // apply the default value 641 for (i = 0; i < defLen; i++) if (!this[i]) { 642 this[i] = defaultValue.charAt(i); 643 } 644 645 return this; 646 }, 647 648 // Removes values that doesnt match the mask from the valueArray 649 // Returns the array without the invalid chars. 650 __removeInvalidChars: function(valueArray, maskNonFixedCharsArray, repeatType) { 651 // removes invalid chars 652 for (var i = 0, y = 0; i < valueArray.length; i++) { 653 if (maskNonFixedCharsArray[y] && this.rules[maskNonFixedCharsArray[y]] && !this.rules[maskNonFixedCharsArray[y]].test(valueArray[i])) { 654 valueArray.splice(i, 1); 655 if (!repeatType) y--; 656 i--; 657 } 658 if (!repeatType) y++; 659 } 660 return valueArray; 661 }, 662 663 // Apply the current input mask to the valueArray and returns it. 664 __applyMask: function(valueArray, maskArray, plus, fixedCharsReg) { 665 if (typeof plus == 'undefined') plus = 0; 666 // apply the current mask to the array of chars 667 for (var i = 0; i < valueArray.length + plus; i++) { 668 if (maskArray[i] && fixedCharsReg.test(maskArray[i])) valueArray.splice(i, 0, maskArray[i]); 669 } 670 return valueArray; 671 }, 672 673 // searches for fixed chars begining from the range start position, till it finds a
673non fixed 674 __extraPositionsTill: function(rangeStart, maskArray, fixedCharsReg) { 675 var extraPos = 0; 676 while (fixedCharsReg.test(maskArray[rangeStart++])) { 677 extraPos++; 678 } 679 return extraPos; 680 }, 681 682 __getNextInput: function(input, selector) { 683 var form = input.form; 684 685 if (form == null) { 686 return null; 687 } 688 689 var formEls = form.elements, 690 initialInputIndex = $.inArray(input, formEls) + 1, 691 len = formEls.length, 692 $input = null, 693 i; 694 695 // look for next input on the form of the pased input 696 for (i = initialInputIndex; i < len; i++) { 697 $input = $(formEls[i]); 698 if (this.__isNextInput($input, selector)) { 699 return $input; 700 } 701 } 702 703 var forms = document.forms, 704 initialFormIndex = $.inArray(input.form, forms) + 1, 705 y, tmpFormEls, _len = forms.length; 706 // look for the next forms for the next input 707 for (y = initialFormIndex; y < _len; y++) { 708 tmpFormEls = forms[y].elements; 709 len = tmpFormEls.length; 710 for (i = 0; i < len; i++) { 711 $input = $(tmpFormEls[i]); 712 if (this.__isNextInput($input, selector)) { 713 return $input; 714 } 715 } 716 } 717 return null; 718 }, 719 720 __isNextInput: function($formEl, selector) { 721 var formEl = $formEl.get(0); 722 return formEl && (formEl.offsetWidth > 0 || formEl.offsetHeight > 0) && formEl.nodeName != 'FIELDSET' && (selector === true || (typeof selector == 'string' && $formEl.is(selector))); 723 }, 724 725 // http://www.bazon.net/mishoo/articles.epl?art_id=1292 726 __setRange: function(input, start, end) { 727 if (typeof end == 'undefined') { 728 end = start; 729 } 730 if (input.setSelectionRange) { 731 input.setSelectionRange(start, end); 732 } else { 733 // assumed IE 734 var range = input.createTextRange(); 735 range.collapse(); 736 range.moveStart('character', start); 737 range.moveEnd('character', end - start); 738 range.select(); 739 } 740 }, 741 742 // adaptation from http://digitarald.de/project/autocompleter/ 743 __getRange: function(input) { 744 if (!$.browser_is_supported_meio.msie && !$.browser_is_supported_meio.android) return { 745 start: input.selectionStart, 746 end: input.selectionEnd 747 }; 748 var pos = { 749 start: 0, 750 end: 0 751 }, 752 range = document.selection.createRange(); 753 pos.start = 0 - range.duplicate().moveStart('character', - 100000); 754 pos.end = pos.start + range.text.length; 755 return pos; 756 }, 757 758 //deprecated 759 unmaskedVal: function(el) { 760 return $(el).val().replace($.mask.fixedCharsRegG, ''); 761 } 762 763 } 764 }); 765 766 $.fn.extend({ 767 setMask: function(options) { 768 return $.mask.set(this, options); 769 }, 770 unsetMask: function() { 771 return $.mask.unset(this); 772 }, 773 //deprecated 774 unmaskedVal: function() { 775 return $.mask.unmaskedVal(this[0]); 776 } 777 }); 778})(jQuery);
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.