vendor: 20,661 bytes, lines 1-541
1/** 2 * jquery.mask.js 3 * @version: v1.14.10 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 }) 104 .on($.jMaskGlobals.useInput ? 'input.mask' : 'keyup.mask', p.behaviour) 105 .on('paste.mask drop.mask', function() { 106 setTimeout(function() { 107 el.keydown().keyup(); 108 }, 100); 109 }) 110 .on('change.mask', function(){ 111 el.data('changed', true); 112 }) 113 .on('blur.mask', function(){ 114 if (oldValue !== p.val() && !el.data('changed')) { 115 el.trigger('change'); 116 } 117 el.data('changed', false); 118 }) 119 // it's very important that this callback remains in this position 120 // otherwhise oldValue it's going to work buggy 121 .on('blur.mask', function() { 122 oldValue = p.val(); 123 }) 124 // select all text on focus 125 .on('focus.mask', function (e) { 126 if (options.selectOnFocus === true) { 127 $(e.target).select(); 128 } 129 }) 130 // clear the value if it not complete the mask 131 .on('focusout.mask', function() { 132 if (options.clearIfNotMatch && !regexMask.test(p.val())) { 133 p.val(''); 134 } 135 }); 136 }, 137 getRegexMask: function() { 138 var maskChunks = [], translation, pattern, optional, recursive, oRecursive, r; 139 140 for (var i = 0; i < mask.length; i++) { 141 translation = jMask.translation[mask.charAt(i)]; 142 143 if (translation) { 144 145 pattern = translation.pattern.toString().replace(/.{1}$|^.{1}/g, ''); 146 optional = translation.optional; 147 recursive = translation.recursive; 148 149 if (recursive) { 150 maskChunks.push(mask.charAt(i)); 151 oRecursive = {digit: mask.charAt(i), pattern: pattern}; 152 } else { 153 maskChunks.push(!optional && !recursive ? pattern : (pattern + '?')); 154 } 155 156 } else { 157 maskChunks.push(mask.charAt(i).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')); 158 } 159 } 160 161 r = maskChunks.join(''); 162 163 if (oRecursive) { 164 r = r.replace(new RegExp('(' + oRecursive.digit + '(.*' + oRecursive.digit + ')?)'), '($1)?') 165 .replace(new RegExp(oRecursive.digit, 'g'), oRecursive.pattern); 166 } 167 168 return new RegExp(r); 169 }, 170 destroyEvents: function() { 171 el.off(['input', 'keydown', 'keyup', 'paste', 'drop', 'blur', 'focusout', ''].join('.mask ')); 172 }, 173 val: function(v) { 174 var isInput = el.is('input'), 175 method = isInput ? 'val' : 'text', 176 r; 177 178 if (arguments.length > 0) { 179 if (el[method]() !== v) { 180 el[method](v); 181 } 182 r = el; 183 } else { 184 r = el[method](); 185 } 186 187 return r; 188 }, 189 calculateCaretPosition: function(caretPos, newVal) { 190 var newValL = newVal.length, 191 oValue = el.data('mask-previus-value') || '', 192 oValueL = oValue.length; 193 194 // edge cases when erasing digits 195 if (el.data('mask-keycode') === 8 && oValue !== newVal) { 196 caretPos = caretPos - (newVal.slice(0, caretPos).length - oValue.slice(0, caretPos).length); 197 198 // edge cases when typing new digits 199 } else if (oValue !== newVal) { 200 // if the cursor is at the end keep it there 201 if (caretPos >= oValueL) { 202 caretPos = newValL; 203 } else { 204 caretPos = caretPos + (newVal.slice(0, caretPos).length - oValue.slice(0, caretPos).length); 205 } 206 } 207 208 return caretPos; 209 }, 210 behaviour: function(e) { 211 e = e || window.event; 212 p.invalid = []; 213 214 var keyCode = el.data('mask-keycode'); 215 216 if ($.inArray(keyCode, jMask.byPassKeys) === -1) { 217 var newVal = p.getMasked(), 218 caretPos = p.getCaret(); 219 220 setTimeout(function(caretPos, newVal) { 221 p.setCaret(p.calculateCaretPosition(caretPos, newVal)); 222 }, 10, caretPos, newVal); 223 224 p.val(newVal); 225 p.setCaret(caretPos); 226 return p.callbacks(e); 227 } 228 }, 229 getMasked: function(skipMaskChars, val) { 230 var buf = [], 231 value = val === undefined ? p.val() : val + '', 232 m = 0, maskLen = mask.length, 233 v = 0, valLen = value.length, 234 offset = 1, addMethod = 'push', 235 resetPos = -1, 236 lastMaskChar, 237 check; 238 239 if (options.reverse) { 240 addMethod = 'unshift'; 241 offset = -1; 242 lastMaskChar = 0; 243 m = maskLen - 1; 244 v = valLen - 1; 245 check = function () { 246 return m > -1 && v > -1; 247 }; 248 } else { 249 lastMaskChar = maskLen - 1; 250 check = function () { 251 return m < maskLen && v < valLen; 252 }; 253 } 254 255 var lastUntranslatedMaskChar; 256 while (check()) { 257 var maskDigit = mask.charAt(m), 258 valDigit = value.charAt(v), 259 translation = jMask.translation[maskDigit]; 260 261 if (translation) { 262 if (valDigit.match(translation.pattern)) { 263 buf[addMethod](valDigit); 264 if (translation.recursive) { 265 if (resetPos === -1) { 266 resetPos = m; 267 } else if (m === lastMaskChar) { 268 m = resetPos - offset; 269 } 270 271 if (lastMaskChar === resetPos) { 272 m -= offset; 273 } 274 } 275 m += offset; 276 } else if (valDigit === lastUntranslatedMaskChar) { 277 // matched the last untranslated (raw) mask character that we encountered 278 // likely an insert offset the mask character from the last entry; fall 279 // through and only increment v 280 lastUntranslatedMaskChar = undefined; 281 } else if (translation.optional) { 282 m += offset; 283 v -= offset; 284 } else if (translation.fallback) { 285 buf[addMethod](translation.fallback); 286 m += offset; 287 v -= offset; 288 } else { 289 p.invalid.push({p: v, v: valDigit, e: translation.pattern}); 290 } 291 v += offset; 292 } else { 293 if (!skipMaskChars) { 294 buf[addMethod](maskDigit); 295 } 296 297 if (valDigit === maskDigit) { 298 v += offset; 299 } else { 300 lastUntranslatedMaskChar = maskDigit; 301 } 302 303 m += offset; 304 } 305 } 306 307 var lastMaskCharDigit = mask.charAt(lastMaskChar); 308 if (maskLen === valLen + 1 && !jMask.translation[lastMaskCharDigit]) { 309 buf.push(lastMaskCharDigit); 310 } 311 312 return buf.join(''); 313 }, 314 callbacks: function (e) { 315 var val = p.val(), 316 changed = val !== oldValue, 317 defaultArgs = [val, e, el, options], 318 callback = function(name, criteria, args) { 319 if (typeof options[name] === 'function' && criteria) { 320 options[name].apply(this, args); 321 } 322 }; 323 324 callback('onChange', changed === true, defaultArgs); 325 callback('onKeyPress', changed === true, defaultArgs); 326 callback('onComplete', val.length === mask.length, defaultArgs); 327 callback('onInvalid', p.invalid.length > 0, [val, e, el, p.invalid, options]); 328 } 329 }; 330 331 el = $(el); 332 var jMask = this, oldValue = p.val(), regexMask; 333 334 mask = typeof mask === 'function' ? mask(p.val(), undefined, el, options) : mask; 335 336 // public methods 337 jMask.mask = mask; 338 jMask.options = options; 339 jMask.remove = function() { 340 var caret = p.getCaret(); 341 p.destroyEvents(); 342 p.val(jMask.getCleanVal()); 343 p.setCaret(caret); 344 return el; 345 }; 346 347 // get value without mask 348 jMask.getCleanVal = function() { 349 return p.getMasked(true); 350 }; 351 352 // get masked value without the value being in the input or element 353 jMask.getMaskedVal = function(val) { 354 return p.getMasked(false, val); 355 }; 356 357 jMask.init = function(onlyMask) { 358 onlyMask = onlyMask || false; 359 options = options || {}; 360 361 jMask.clearIfNotMatch = $.jMaskGlobals.clearIfNotMatch; 362 jMask.byPassKeys = $.jMaskGlobals.byPassKeys; 363 jMask.translation = $.extend({}, $.jMaskGlobals.translation, options.translation); 364 365 jMask = $.extend(true, {}, jMask, options); 366 367 regexMask = p.getRegexMask(); 368 369 if (onlyMask) { 370 p.events(); 371 p.val(p.getMasked()); 372 } else { 373 if (options.placeholder) { 374 el.attr('placeholder' , options.placeholder); 375 } 376 377 // this is necessary, otherwise if the user submit the form 378 // and then press the "back" button, the autocomplete will erase 379 // the data. Works fine on IE9+, FF, Opera, Safari. 380 if (el.data('mask')) { 381 el.attr('autocomplete', 'off'); 382 } 383 384 // detect if is necessary let the user type freely. 385 // for is a lot faster than forEach. 386 for (var i = 0, maxlength = true; i < mask.length; i++) { 387 var translation = jMask.translation[mask.charAt(i)]; 388 if (translation && translation.recursive) { 389 maxlength = false; 390 break; 391 } 392 } 393 394 if (maxlength) { 395 el.attr('maxlength', mask.length); 396 } 397 398 p.destroyEvents(); 399 p.events(); 400 401 var caret = p.getCaret(); 402 p.val(p.getMasked()); 403 p.setCaret(caret); 404 } 405 }; 406 407 jMask.init(!el.is('input')); 408 }; 409 410 $.maskWatchers = {}; 411 var HTMLAttributes = function () { 412 var input = $(this), 413 options = {}, 414 prefix = 'data-mask-', 415 mask = input.attr('data-mask'); 416 417 if (input.attr(prefix + 'reverse')) { 418 options.reverse = true; 419 } 420 421 if (input.attr(prefix + 'clearifnotmatch')) { 422 options.clearIfNotMatch = true; 423 } 424 425 if (input.attr(prefix + 'selectonfocus') === 'true') { 426 options.selectOnFocus = true; 427 } 428 429 if (notSameMaskObject(input, mask, options)) { 430 return input.data('mask', new Mask(this, mask, options)); 431 } 432 }, 433 notSameMaskObject = function(field, mask, options) { 434 options = options || {}; 435 var maskObject = $(field).data('mask'), 436 stringify = JSON.stringify, 437 value = $(field).val() || $(field).text(); 438 try { 439 if (typeof mask === 'function') { 440 mask = mask(value); 441 } 442 return typeof maskObject !== 'object' || stringify(maskObject.options) !== stringify(options) || maskObject.mask !== mask; 443 } catch (e) {} 444 }, 445 eventSupported = function(eventName) { 446 var el = document.createElement('div'), isSupported; 447 448 eventName = 'on' + eventName; 449 isSupported = (eventName in el); 450 451 if ( !isSupported ) { 452 el.setAttribute(eventName, 'return;'); 453 isSupported = typeof el[eventName] === 'function'; 454 } 455 el = null; 456 457 return isSupported; 458 }; 459 460 $.fn.mask = function(mask, options) { 461 options = options || {}; 462 var selector = this.selector, 463 globals = $.jMaskGlobals, 464 interval = globals.watchInterval, 465 watchInputs = options.watchInputs || globals.watchInputs, 466 maskFunction = function() { 467 if (notSameMaskObject(this, mask, options)) { 468 return $(this).data('mask', new Mask(this, mask, options)); 469 } 470 }; 471 472 $(this).each(maskFunction); 473 474 if (selector && selector !== '' && watchInputs) { 475 clearInterval($.maskWatchers[selector]); 476 $.maskWatchers[selector] = setInterval(function(){ 477 $(document).find(selector).each(maskFunction); 478 }, interval); 479 } 480 return this; 481 }; 482 483 $.fn.masked = function(val) { 484 return this.data('mask').getMaskedVal(val); 485 }; 486 487 $.fn.unmask = function() { 488 clearInterval($.maskWatchers[this.selector]); 489 delete $.maskWatchers[this.selector]; 490 return this.each(function() { 491 var dataMask = $(this).data('mask'); 492 if (dataMask) { 493 dataMask.remove().removeData('mask'); 494 } 495 }); 496 }; 497 498 $.fn.cleanVal = function() { 499 return this.data('mask').getCleanVal(); 500 }; 501 502 $.applyDataMask = function(selector) { 503 selector = selector || $.jMaskGlobals.maskElements; 504 var $selector = (selector instanceof $) ? selector : $(selector); 505 $selector.filter($.jMaskGlobals.dataMaskAttr).each(HTMLAttributes); 506 }; 507 508 var globals = { 509 maskElements: 'input,td,span,div', 510 dataMaskAttr: '*[data-mask]', 511 dataMask: true, 512 watchInterval: 300, 513 watchInputs: true, 514 // old versions of chrome dont work great with input event 515 useInput: !/Chrome\/[2-4][0-9]|SamsungBrowser/.test(window.navigator.userAgent) && eventSupported('input'), 516 watchDataMask: false, 517 byPassKeys: [9, 16, 17, 18, 36, 37, 38, 39, 40, 91], 518 translation: { 519 '0': {pattern: /\d/}, 520 '9': {pattern: /\d/, optional: true}, 521 '#': {pattern: /\d/, recursive: true}, 522 'A': {pattern: /[a-zA-Z0-9]/}, 523 'S': {pattern: /[a-zA-Z]/} 524 } 525 }; 526 527 $.jMaskGlobals = $.jMaskGlobals || {}; 528 globals = $.jMaskGlobals = $.extend(true, {}, globals, $.jMaskGlobals); 529 530 // looking for inputs with data-mask attribute 531 if (globals.dataMask) { 532 $.applyDataMask(); 533 } 534 535 setInterval(function() { 536 if ($.jMaskGlobals.watchDataMask) { 537 $.applyDataMask(); 538 } 539 }, globals.watchInterval); 540}, window.jQuery, window.Zepto)); 541
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.