1/* 2 Masked Input plugin for jQuery 3 Copyright (c) 2007-2009 Josh Bush (digitalbush.com) 4 Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license) 5 Version: 1.2.2 (03/09/2009 22:39:06) 6*/ 7(function($) { 8 var pasteEventName = ($.browser.msie ? 'paste' : 'input') + ".mask"; 9 var iPhone = (window.orientation != undefined); 10 11 $.mask = { 12 //Predefined character definitions 13 definitions: { 14 '9': "[0-9]", 15 'a': "[A-Za-z]", 16 'Ñ': "[Ð-Яа-Ñ]", 17 '*': "[^]" 18 19 } 20 }; 21 22 $.fn.extend({ 23 //Helper Function for Caret positioning 24 caret: function(begin, end) { 25 if (this.length == 0) return; 26 if (typeof begin == 'number') { 27 end = (typeof end == 'number') ? end : begin; 28 return this.each(function() { 29 if (this.setSelectionRange) { 30 this.focus(); 31 this.setSelectionRange(begin, end); 32 } else if (this.createTextRange) { 33 var range = this.createTextRange(); 34 range.collapse(true); 35 range.moveEnd('character', end); 36 range.moveStart('character', begin); 37 range.select(); 38 } 39 }); 40 } else { 41 if (this[0].setSelectionRange) { 42 begin = this[0].selectionStart; 43 end = this[0].selectionEnd; 44 } else if (document.selection && document.selection.createRange) { 45 var range = document.selection.createRange(); 46 begin = 0 - range.duplicate().moveStart('character', -100000); 47 end = begin + range.text.length; 48 } 49 return { begin: begin, end: end }; 50 } 51 }, 52 unmask: function() { return this.trigger("unmask"); }, 53 mask: function(mask, settings) { 54 if (!mask && this.length > 0) { 55 var input = $(this[0]); 56 var tests = input.data("tests"); 57 return $.map(input.data("buffer"), function(c, i) { 58 return tests[i] ? c : null; 59 }).join(''); 60 } 61 settings = $.extend({ 62 placeholder: "_", 63 completed: null 64 }, settings); 65 66 var defs = $.mask.definitions; 67 var tests = []; 68 var partialPosition = mask.length; 69 var firstNonMaskPos = null; 70 var len = mask.length; 71 72 $.each(mask.split(""), function(i, c) { 73 if (c == '?') { 74 len--; 75 partialPosition = i; 76 } else if (defs[c]) { 77 tests.push(new RegExp(defs[c])); 78 if(firstNonMaskPos==null) 79 firstNonMaskPos = tests.length - 1; 80 } else { 81 tests.push(null); 82 } 83 }); 84 85 return this.each(function() { 86 var input = $(this); 87 var buffer = $.map(mask.split(""), function(c, i) { if (c != '?') return defs[c] ? settings.placeholder : c }); 88 var ignore = false; //Variable for ignoring control keys 89 var focusText = input.val(); 90 91 input.data("buffer", buffer).data("tests", tests); 92 93 function seekNext(pos) { 94 while (++pos <= len && !tests[pos]); 95 return pos; 96 }; 97 98 function shiftL(pos) { 99 while (!tests[pos] && --pos >= 0); 100 for (var i = pos; i < len; i++) { 101 if (tests[i]) { 102 buffer[i] = settings.placeholder; 103 var j = seekNext(i); 104 if (j < len && tests[i].test(buffer[j])) { 105 buffer[i] = buffer[j]; 106 } else 107 break; 108 } 109 } 110 writeBuffer(); 111 input.caret(Math.max(firstNonMaskPos, pos)); 112 }; 113 114 function shiftR(pos) { 115 for (var i = pos, c = settings.placeholder; i < len; i++) { 116 if (tests[i]) { 117 var j = seekNext(i); 118 var t = buffer[i]; 119 buffer[i] = c; 120 if (j < len && tests[j].test(t)) 121 c = t; 122 else 123 break; 124 } 125 } 126 }; 127 128 function keydownEvent(e) { 129 var pos = $(this).caret(); 130 var k = e.keyCode; 131 ignore = (k < 16 || (k > 16 && k < 32) || (k > 32 && k < 41)); 132 133 //delete selection before proceeding 134 if ((pos.begin - pos.end) != 0 && (!ignore || k == 8 || k == 46)) 135 clearBuffer(pos.begin, pos.end); 136 137 //backspace, delete, and escape get special treatment 138 if (k == 8 || k == 46 || (iPhone && k == 127)) {//backspace/delete 139 shiftL(pos.begin + (k == 46 ? 0 : -1)); 140 return false; 141 } else if (k == 27) {//escape 142 input.val(focusText); 143 input.caret(0, checkVal()); 144 return false; 145 } 146 }; 147 148 function keypressEvent(e) { 149 if (ignore) { 150 ignore = false;
151 //Fixes Mac FF bug on backspace 152 return (e.keyCode == 8) ? false : null; 153 } 154 e = e || window.event; 155 var k = e.charCode || e.keyCode || e.which; 156 var pos = $(this).caret(); 157 158 if (e.ctrlKey || e.altKey || e.metaKey) {//Ignore 159 return true; 160 } else if ((k >= 32 && k <= 125) || k > 186) {//typeable characters 161 var p = seekNext(pos.begin - 1); 162 if (p < len) { 163 var c = String.fromCharCode(k); 164 if (tests[p].test(c)) { 165 shiftR(p); 166 buffer[p] = c; 167 writeBuffer(); 168 var next = seekNext(p); 169 $(this).caret(next); 170 if (settings.completed && next == len) 171 settings.completed.call(input); 172 } 173 } 174 } 175 return false; 176 }; 177 178 function clearBuffer(start, end) { 179 for (var i = start; i < end && i < len; i++) { 180 if (tests[i]) 181 buffer[i] = settings.placeholder; 182 } 183 }; 184 185 function writeBuffer() { return input.val(buffer.join('')).val(); }; 186 187 function checkVal(allow) { 188 //try to place characters where they belong 189 var test = input.val(); 190 var lastMatch = -1; 191 for (var i = 0, pos = 0; i < len; i++) { 192 if (tests[i]) { 193 buffer[i] = settings.placeholder; 194 while (pos++ < test.length) { 195 var c = test.charAt(pos - 1); 196 if (tests[i].test(c)) { 197 buffer[i] = c; 198 lastMatch = i; 199 break; 200 } 201 } 202 if (pos > test.length) 203 break; 204 } else if (buffer[i] == test[pos] && i!=partialPosition) { 205 pos++; 206 lastMatch = i; 207 } 208 } 209 if (!allow && lastMatch + 1 < partialPosition) { 210 input.val(""); 211 clearBuffer(0, len); 212 } else if (allow || lastMatch + 1 >= partialPosition) { 213 writeBuffer(); 214 if (!allow) input.val(input.val().substring(0, lastMatch + 1)); 215 } 216 return (partialPosition ? i : firstNonMaskPos); 217 }; 218 219 if (!input.attr("readonly")) 220 input 221 .one("unmask", function() { 222 input 223 .unbind(".mask") 224 .removeData("buffer") 225 .removeData("tests"); 226 }) 227 .bind("focus.mask", function() { 228 focusText = input.val(); 229 var pos = checkVal(); 230 writeBuffer(); 231 setTimeout(function() { 232 if (pos == mask.length) 233 input.caret(0, pos); 234 else 235 input.caret(pos); 236 }, 0); 237 }) 238 .bind("blur.mask", function() { 239 checkVal(); 240 if (input.val() != focusText) 241 input.change(); 242 }) 243 .bind("keydown.mask", keydownEvent) 244 .bind("keypress.mask", keypressEvent) 245 .bind(pasteEventName, function() { 246 setTimeout(function() { input.caret(checkVal(true)); }, 0); 247 }); 248 249 checkVal(); //Perform initial check for existing values 250 }); 251 } 252 }); 253})(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.