vendor: 22,666 bytes, lines 1-597
1/** 2 * jquery.mask.js 3 * @version: v1.14.11 4 * @author: Igor Escobar 5 * 6 * Created by Igor Escobar on 2012-03-10. Please report any bug at http://blog.igorescobar.com 7 * 8 * Copyright (c) 2012 Igor Escobar http://blog.igorescobar.com 9 * 10 * The MIT License (http://www.opensource.org/licenses/mit-license.php) 11 * 12 * Permission is hereby granted, free of charge, to any person 13 * obtaining a copy of this software and associated documentation 14 * files (the "Software"), to deal in the Software without 15 * restriction, including without limitation the rights to use, 16 * copy, modify, merge, publish, distribute, sublicense, and/or sell 17 * copies of the Software, and to permit persons to whom the 18 * Software is furnished to do so, subject to the following 19 * conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 26 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 28 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 29 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 31 * OTHER DEALINGS IN THE SOFTWARE. 32 */ 33 34/* jshint laxbreak: true */ 35/* jshint maxcomplexity:17 */ 36/* global define */ 37 38'use strict'; 39 40// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere. 41// https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js 42(function (factory, jQuery, Zepto) { 43 44 if (typeof define === 'function' && define.amd) { 45 define(['jquery'], factory); 46 } else if (typeof exports === 'object') { 47 module.exports = factory(require('jquery')); 48 } else { 49 factory(jQuery || Zepto); 50 } 51 52}(function ($) { 53 54 var Mask = function (el, mask, options) { 55 56 var p = { 57 invalid: [], 58 getCaret: function () { 59 try { 60 var sel, 61 pos = 0, 62 ctrl = el.get(0), 63 dSel = document.selection, 64 cSelStart = ctrl.selectionStart; 65 66 // IE Support 67 if (dSel && navigator.appVersion.indexOf('MSIE 10') === -1) { 68 sel = dSel.createRange(); 69 sel.moveStart('character', -p.val().length); 70 pos = sel.text.length; 71 } 72 // Firefox support 73 else if (cSelStart || cSelStart === '0') { 74 pos = cSelStart; 75 } 76 77 return pos; 78 } catch (e) {} 79 }, 80 setCaret: function(pos) { 81 try { 82 if (el.is(':focus')) { 83 var range, ctrl = el.get(0); 84 85 // Firefox, WebKit, etc.. 86 if (ctrl.setSelectionRange) { 87 ctrl.setSelectionRange(pos, pos); 88 } else { // IE 89 range = ctrl.createTextRange(); 90 range.collapse(true); 91 range.moveEnd('character', pos); 92 range.moveStart('character', pos); 93 range.select(); 94 } 95 } 96 } catch (e) {} 97 }, 98 events: function() { 99 el 100 .on('keydown.mask', function(e) { 101 el.data('mask-keycode', e.keyCode || e.which); 102 el.data('mask-previus-value', el.val()); 103 el.data('mask-previus-caret-pos', p.getCaret()); 104 p.maskDigitPosMapOld = p.maskDigitPosMap; 105 }) 106 .on($.jMaskGlobals.useInput ? 'input.mask' : 'keyup.mask', p.behaviour) 107 .on('paste.mask drop.mask', function() { 108 setTimeout(function() { 109 el.keydown().keyup(); 110 }, 100); 111 }) 112 .on('change.mask', function(){ 113 el.data('changed', true); 114 }) 115 .on('blur.mask', function(){ 116 if (oldValue !== p.val() && !el.data('changed')) { 117 el.trigger('change'); 118 } 119 el.data('changed', false); 120 }) 121 // it's very important that this callback remains in this position 122 // otherwhise oldValue it's going to work buggy 123 .on('blur.mask', function() { 124 oldValue = p.val(); 125 }) 126 // select all text on focus 127 .on('focus.mask', function (e) { 128 if (options.selectOnFocus === true) { 129 $(e.target).select(); 130 } 131 }) 132 // clear the value if it not complete the mask 133 .on('focusout.mask', function() { 134 if (options.clearIfNotMatch && !regexMask.test(p.val())) { 135 p.val(''); 136 } 137 }); 138 }, 139 getRegexMask: function() { 140 var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r; 141 142 for (var i = 0; i < mask.length; i++) { 143 translation = jMask.translation[mask.charAt(i)]; 144 145 if (translation) { 146 147 pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, ''); 148 optional = translation.optional; 149 recursive = translation.recursive; 150 151 if (recursive) { 152 maskChunks.push(mask.charAt(i)); 153 oRecursive = {digit: mask.charAt(i), pattern: pattern}; 154 } else { 155 maskChunks.push(!optional && !recursive ? pattern : (pattern + '?')); 156 } 157 158 } else { 159 maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')); 160 } 161 } 162 163 r = maskChunks.join(''); 164 165 if (oRecursive) { 166 r = r.replace(new RegExp('(' + oRecursive.digit + '(.*' + oRecursive.digit + ')?)'), '($1)?') 167 .replace(new RegExp(oRecursive.digit, 'g'), oRecursive.pattern); 168 } 169 170 return new RegExp(r); 171 }, 172 destroyEvents: function() { 173 el.off(['input', 'keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask ')); 174 }, 175 val: function(v) { 176 var isInput = el.is('input'), 177 method = isInput ? 'val' : 'text', 178 r; 179 180 if (arguments.length > 0) { 181 if (el[method]() !== v) { 182 el[method](v); 183 } 184 r = el; 185 } else { 186 r = el[method](); 187 } 188 189 return r; 190 }, 191 calculateCaretPosition: function() { 192 var oldVal = el.data('mask-previus-value') || '', 193 newVal = p.getMasked(), 194 caretPosNew = p.getCaret(); 195 if (oldVal !== newVal) { 196 var caretPosOld = el.data('mask-previus-caret-pos') || 0, 197 newValL = newVal.length, 198 oldValL = oldVal.length, 199 maskDigitsBeforeCaret = 0, 200 maskDigitsAfterCaret = 0, 201 maskDigitsBeforeCaretAll = 0, 202 maskDigitsBeforeCaretAllOld = 0, 203 i = 0; 204 205 for (i = caretPosNew; i < newValL; i++) { 206 if (!p.maskDigitPosMap[i]) { 207 break; 208 } 209 maskDigitsAfterCaret++; 210 } 211 212 for (i = caretPosNew - 1; i >= 0; i--) { 213 if (!p.maskDigitPosMap[i]) { 214 break; 215 } 216 maskDigitsBeforeCaret++; 217 } 218 219 for (i = caretPosNew - 1; i >= 0; i--) { 220 if (p.maskDigitPosMap[i]) { 221 maskDigitsBeforeCaretAll++; 222 } 223 } 224 225 for (i = caretPosOld - 1; i >= 0; i--) { 226 if (p.maskDigitPosMapOld[i]) { 227 maskDigitsBeforeCaretAllOld++; 228 } 229 } 230 231 if (caretPosNew > oldValL) { 232 // if the cursor is at the end keep it there 233 caretPosNew = newValL; 234 } 235 else if (caretPosOld >= caretPosNew && caretPosOld !== oldValL) { 236 if (!p.maskDigitPosMapOld[caretPosNew]) { 237 var caretPos = caretPosNew; 238 caretPosNew -= maskDigitsBeforeCaretAllOld - maskDigitsBeforeCaretAll; 239 caretPosNew -= maskDigitsBeforeCaret; 240 if (p.maskDigitPosMap[caretPosNew]) { 241 caretPosNew = caretPos; 242 } 243 } 244 } 245 else if (caretPosNew > caretPosOld) { 246 caretPosNew += maskDigitsBeforeCaretAll - maskDigitsBeforeCaretAllOld; 247 caretPosNew += maskDigitsAfterCaret; 248 } 249 } 250 return caretPosNew; 251 }, 252 behaviour: function(e) { 253 e = e || window.event; 254 p.invalid = []; 255 256 var keyCode = el.data('mask-keycode'); 257 258 if ($.inArray(keyCode, jMask.byPassKeys) === -1) { 259 var newVal = p.getMasked(), 260 caretPos = p.getCaret(); 261 262 setTimeout(function() { 263 p.setCaret(p.calculateCaretPosition()); 264 }, 10); 265 266 p.val(newVal); 267 p.setCaret(caretPos); 268 return p.callbacks(e); 269 } 270 }, 271 getMasked: function(skipMaskChars, val) { 272 var buf = [], 273 value = val === undefined ? p.val() : val + '', 274 m = 0, maskLen = mask.length, 275 v = 0, valLen = value.length, 276 offset = 1, addMethod = 'push', 277 resetPos = -1, 278 maskDigitCount = 0, 279 maskDigitPosArr = [], 280 lastMaskChar, 281 check; 282 283 if (options.reverse) { 284 addMethod = 'unshift'; 285 offset = -1; 286 lastMaskChar = 0; 287 m = maskLen - 1; 288 v = valLen - 1; 289 check = function () { 290 return m > -1 && v > -1; 291 }; 292 } else { 293 lastMaskChar = maskLen - 1; 294 check = function () { 295 return m < maskLen && v < valLen; 296 }; 297 } 298 299 var lastUntranslatedMaskChar; 300 while (check()) { 301 var maskDigit = mask.charAt(m), 302 valDigit = value.charAt(v), 303 translation = jMask.translation[maskDigit]; 304 305 if (translation) { 306 if (valDigit.match(translation.pattern)) { 307 buf[addMethod](valDigit); 308 if (translation.recursive) { 309 if (resetPos === -1) { 310 resetPos = m; 311 } else if (m === lastMaskChar) { 312 m = resetPos - offset; 313 } 314 315 if (lastMaskChar === resetPos) { 316 m -= offset; 317 } 318 } 319 m += offset; 320 } else if (valDigit === lastUntranslatedMaskChar) { 321 // matched the last untranslated (raw) mask character that we encountered 322 // likely an insert offset the mask character from the last entry; fall 323 // through and only increment v 324 maskDigitCount--; 325 lastUntranslatedMaskChar = undefined; 326 } else if (translation.optional) { 327 m += offset; 328 v -= offset; 329 } else if (translation.fallback) { 330 buf[addMethod](translation.fallback); 331 m += offset; 332 v -= offset; 333 } else { 334 p.invalid.push({p: v, v: valDigit, e: translation.pattern}); 335 } 336 v += offset; 337 } else { 338 if (!skipMaskChars) { 339 buf[addMethod](maskDigit); 340 } 341 342 if (valDigit === maskDigit) { 343 maskDigitPosArr.push(v); 344 v += offset; 345 } else { 346 lastUntranslatedMaskChar = maskDigit; 347 maskDigitPosArr.push(v + maskDigitCount); 348 maskDigitCount++; 349 } 350 351 m += offset; 352 } 353 } 354 355 var lastMaskCharDigit = mask.charAt(lastMaskChar); 356 if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) { 357 buf.push(lastMaskCharDigit); 358 } 359 360 var newVal = buf.join(''); 361 p.mapMaskdigitPositions(newVal, maskDigitPosArr, valLen); 362 return newVal; 363 }, 364 mapMaskdigitPositions: function(newVal, maskDigitPosArr, valLen) { 365 var maskDiff = options.reverse ? newVal.length - valLen : 0; 366 p.maskDigitPosMap = {}; 367 for (var i = 0; i < maskDigitPosArr.length; i++) { 368 p.maskDigitPosMap[maskDigitPosArr[i] + maskDiff] = 1; 369 } 370 }, 371 callbacks: function (e) { 372 var val = p.val(), 373 changed = val !== oldValue, 374 defaultArgs = [val, e, el, options], 375 callback = function(name, criteria, args) { 376 if (typeof options[name] === 'function' && criteria) { 377 options[name].apply(this, args); 378 } 379 }; 380 381 callback('onChange', changed === true, defaultArgs); 382 callback('onKeyPress', changed === true, defaultArgs); 383 callback('onComplete', val.length === mask.length, defaultArgs); 384 callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]); 385 } 386 }; 387 388 el = $(el); 389 var jMask = this, oldValue = p.val(), regexMask; 390 391 mask = typeof mask === 'function' ? mask(p.val(), undefined, el, options) : mask; 392 393 // public methods 394 jMask.mask = mask; 395 jMask.options = options; 396 jMask.remove = function() { 397 var caret = p.getCaret(); 398 p.destroyEvents(); 399 p.val(jMask.getCleanVal()); 400 p.setCaret(caret); 401 return el; 402 }; 403 404 // get value without mask 405 jMask.getCleanVal = function() { 406 return p.getMasked(true); 407 }; 408 409 // get masked value without the value being in the input or element 410 jMask.getMaskedVal = function(val) { 411 return p.getMasked(false, val); 412 }; 413 414 jMask.init = function(onlyMask) { 415 onlyMask = onlyMask || false; 416 options = options || {}; 417 418 jMask.clearIfNotMatch = $.jMaskGlobals.clearIfNotMatch; 419 jMask.byPassKeys = $.jMaskGlobals.byPassKeys; 420 jMask.translation = $.extend({}, $.jMaskGlobals.translation, options.translation); 421 422 jMask = $.extend(true, {}, jMask, options); 423 424 regexMask = p.getRegexMask(); 425 426 if (onlyMask) { 427 p.events(); 428 p.val(p.getMasked()); 429 } else { 430 if (options.placeholder) { 431 el.attr('placeholder' , options.placeholder); 432 } 433 434 // this is necessary, otherwise if the user submit the form 435 // and then press the "back" button, the autocomplete will erase 436 // the data. Works fine on IE9+, FF, Opera, Safari. 437 if (el.data('mask')) { 438 el.attr('autocomplete', 'off'); 439 } 440 441 // detect if is necessary let the user type freely. 442 // for is a lot faster than forEach. 443 for (var i = 0, maxlength = true; i < mask.length; i++) { 444 var translation = jMask.translation[mask.charAt(i)]; 445 if (translation && translation.recursive) { 446 maxlength = false; 447 break; 448 } 449 } 450 451 if (maxlength) { 452 el.attr('maxlength', mask.length); 453 } 454 455 p.destroyEvents(); 456 p.events(); 457 458 var caret = p.getCaret(); 459 p.val(p.getMasked()); 460 p.setCaret(caret); 461 } 462 }; 463 464 jMask.init(!el.is('input')); 465 }; 466 467 $.maskWatchers = {}; 468 var HTMLAttributes = function () { 469 var input = $(this), 470 options = {}, 471 prefix = 'data-mask-', 472 mask = input.attr('data-mask'); 473 474 if (input.attr(prefix + 'reverse')) { 475 options.reverse = true; 476 } 477 478 if (input.attr(prefix + 'clearifnotmatch')) { 479 options.clearIfNotMatch = true; 480 } 481 482 if (input.attr(prefix + 'selectonfocus') === 'true') { 483 options.selectOnFocus = true; 484 } 485 486 if (notSameMaskObject(input, mask, options)) { 487 return input.data('mask', new Mask(this, mask, options)); 488 } 489 }, 490 notSameMaskObject = function(field, mask, options) { 491 options = options || {}; 492 var maskObject = $(field).data('mask'), 493 stringify = JSON.stringify, 494 value = $(field).val() || $(field).text(); 495 try { 496 if (typeof mask === 'function') { 497 mask = mask(value); 498 } 499 return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask; 500 } catch (e) {} 501 }, 502 eventSupported = function(eventName) { 503 var el = document.createElement('div'), isSupported; 504 505 eventName = 'on' + eventName; 506 isSupported = (eventName in el); 507 508 if ( !isSupported ) { 509 el.setAttribute(eventName, 'return;'); 510 isSupported = typeof el[eventName] === 'function'; 511 } 512 el = null; 513 514 return isSupported; 515 }; 516 517 $.fn.mask = function(mask, options) { 518 options = options || {}; 519 var selector = this.selector, 520 globals = $.jMaskGlobals, 521 interval = globals.watchInterval, 522 watchInputs = options.watchInputs || globals.watchInputs, 523 maskFunction = function() { 524 if (notSameMaskObject(this, mask, options)) { 525 return $(this).data('mask', new Mask(this, mask, options)); 526 } 527 }; 528 529 $(this).each(maskFunction); 530 531 if (selector && selector !== '' && watchInputs) { 532 clearInterval($.maskWatchers[selector]); 533 $.maskWatchers[selector] = setInterval(function(){ 534 $(document).find(selector).each(maskFunction); 535 }, interval); 536 } 537 return this; 538 }; 539 540 $.fn.masked = function(val) { 541 return this.data('mask').getMaskedVal(val); 542 }; 543 544 $.fn.unmask = function() { 545 clearInterval($.maskWatchers[this.selector]); 546 delete $.maskWatchers[this.selector]; 547 return this.each(function() { 548 var dataMask = $(this).data('mask'); 549 if (dataMask) { 550 dataMask.remove().removeData('mask'); 551 } 552 }); 553 }; 554 555 $.fn.cleanVal = function() { 556 return this.data('mask').getCleanVal(); 557 }; 558 559 $.applyDataMask = function(selector) { 560 selector = selector || $.jMaskGlobals.maskElements; 561 var $selector = (selector instanceof $) ? selector : $(selector); 562 $selector.filter($.jMaskGlobals.dataMaskAttr).each(HTMLAttributes); 563 }; 564 565 var globals = { 566 maskElements: 'input,td,span,div', 567 dataMaskAttr: '*[data-mask]', 568 dataMask: true, 569 watchInterval: 300, 570 watchInputs: true, 571 // old versions of chrome dont work great with input event 572 useInput: !/Chrome\/[2-4][0-9]|SamsungBrowser/.test(window.navigator.userAgent) && eventSupported('input'), 573 watchDataMask: false, 574 byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91], 575 translation: { 576 '0': {pattern: /\d/}, 577 '9': {pattern: /\d/, optional: true}, 578 '#': {pattern: /\d/, recursive: true}, 579 'A': {pattern: /[a-zA-Z0-9]/}, 580 'S': {pattern: /[a-zA-Z]/} 581 } 582 }; 583 584 $.jMaskGlobals = $.jMaskGlobals || {}; 585 globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals); 586 587 // looking for inputs with data-mask attribute 588 if (globals.dataMask) { 589 $.applyDataMask(); 590 } 591 592 setInterval(function() { 593 if ($.jMaskGlobals.watchDataMask) { 594 $.applyDataMask(); 595 } 596 }, globals.watchInterval); 597}, window.jQuery, window.Zepto));
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.