1function getPasteEvent() { 2 var el = document.createElement('input'), 3 name = 'onpaste'; 4 el.setAttribute(name, ''); 5 return (typeof el[name] === 'function')?'paste':'input'; 6} 7 8var pasteEventName = getPasteEvent() + ".mask", 9 ua = navigator.userAgent, 10 iPhone = /iphone/i.test(ua), 11 android=/android/i.test(ua), 12 caretTimeoutId; 13 14$.mask = { 15 //Predefined character definitions 16 definitions: { 17 '9': "[0-9]", 18 'a': "[A-Za-z]", 19 //ÐÑпÑавление [A-Za-z0-9] на [A-Za-z0-9а-ÑÐ-ЯÑÐ] 20 '*': "[A-Za-z0-9а-ÑÐ-ЯÑÐ]" 21 }, 22 dataName: "rawMaskFn", 23 placeholder: '_', 24}; 25 26$.fn.extend({ 27 //Helper Function for Caret positioning 28 caret: function(begin, end) { 29 var range; 30 31 if (this.length === 0 || this.is(":hidden")) { 32 return; 33 } 34 35 if (typeof begin == 'number') { 36 end = (typeof end === 'number') ? end : begin; 37 return this.each(function() { 38 if (this.setSelectionRange) { 39 this.setSelectionRange(begin, end); 40 } else if (this.createTextRange) { 41 range = this.createTextRange(); 42 range.collapse(true); 43 range.moveEnd('character', end); 44 range.moveStart('character', begin); 45 range.select(); 46 } 47 }); 48 } else { 49 if (this[0].setSelectionRange) { 50 begin = this[0].selectionStart; 51 end = this[0].selectionEnd; 52 } else if (document.selection && document.selection.createRange) { 53 range = document.selection.createRange(); 54 begin = 0 - range.duplicate().moveStart('character', -100000); 55 end = begin + range.text.length; 56 } 57 return { begin: begin, end: end }; 58 } 59 }, 60 unmask: function() { 61 return this.trigger("unmask"); 62 }, 63 mask: function(mask, settings) { 64 var input, 65 defs, 66 tests, 67 partialPosition, 68 firstNonMaskPos, 69 len; 70 71 if (!mask && this.length > 0) { 72 input = $(this[0]); 73 return input.data($.mask.dataName)(); 74 } 75 settings = $.extend({ 76 placeholder: $.mask.placeholder, // Load default placeholder 77 completed: null 78 }, settings); 79 80 81 defs = $.mask.definitions; 82 tests = []; 83 partialPosition = len = mask.length; 84 firstNonMaskPos = null; 85 86 $.each(mask.split(""), function(i, c) { 87 if (c == '?') { 88 len--; 89 partialPosition = i; 90 } else if (defs[c]) { 91 tests.push(new RegExp(defs[c])); 92 if (firstNonMaskPos === null) { 93 firstNonMaskPos = tests.length - 1; 94 } 95 } else { 96 tests.push(null); 97 } 98 }); 99 100 return this.trigger("unmask").each(function() { 101 var input = $(this), 102 buffer = $.map( 103 mask.split(""), 104 function(c, i) { 105 if (c != '?') { 106 return defs[c] ? settings.placeholder : c; 107 } 108 }), 109 focusText = input.val(); 110 111 function seekNext(pos) { 112 while (++pos < len && !tests[pos]); 113 return pos; 114 } 115 116 function seekPrev(pos) { 117 while (--pos >= 0 && !tests[pos]); 118 return pos; 119 } 120 121 function shiftL(begin,end) { 122 var i, 123 j; 124 125 if (begin<0) { 126 return; 127 } 128 129 for (i = begin, j = seekNext(end); i < len; i++) { 130 if (tests[i]) { 131 if (j < len && tests[i].test(buffer[j])) { 132 buffer[i] = buffer[j]; 133 buffer[j] = settings.placeholder; 134 } else { 135 break; 136 } 137 138 j = seekNext(j); 139 } 140 } 141 writeBuffer(); 142 input.caret(Math.max(firstNonMaskPos, begin)); 143 } 144 145 function shiftR(pos) { 146 var i, 147 c, 148 j, 149 t; 150 151 for (i = pos, c = settings.placeholder; i < len; i++) { 152 if (tests[i]) { 153 j = seekNext(i); 154 t = buffer[i]; 155 buffer[i] = c; 156 if (j < len && tests[j].test(t)) { 157 c = t; 158 } else { 159 break; 160 } 161 } 162 } 163 } 164 165 function keydownEvent(e) { 166 var k = e.which, 167 pos, 168 begin, 169 end; 170 171 //backspace, delete, and escape get special treatment 172 if (k === 8 || k === 46 || (iPhone && k === 127)) { 173 pos = input.caret(); 174 begin = pos.begin; 175 end = pos.end; 176 177 if (end - begin === 0) { 178 begin=k!==46?seekPrev(begin):(end=seekNext(begin-1)); 179 end=k===46?seekNext(end):end; 180 } 181 clearBuffer(begin, end); 182 shiftL(begin, end - 1); 183 184 e.preventDefault(); 185 } else if (k == 27) {//escape 186 input.val(focusText); 187 input.caret(0, checkVal()); 188 e.preventDefault(); 189 } 190 } 191 192 function keypressEvent(e) { 193 var k = e.which, 194 pos = input.caret(), 195 p, 196 c, 197 next; 198 199 if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore 200 return; 201 } else if (k) { 202 if (pos.end - pos.begin !== 0){ 203 clearBuffer(pos.begin, pos.end); 204 shiftL(pos.begin, pos.end-1); 205 } 206 207 p = seekNext(pos.begin - 1); 208 if (p < len) { 209 c = String.fromCharCode(k); 210 if (tests[p].test(c)) { 211 shiftR(p); 212 213 buffer[p] = c; 214 writeBuffer(); 215 next = seekNext(p); 216 217 if(android){ 218 setTimeout($.proxy($.fn.caret,input,next),0); 219 }else{ 220 input.caret(next); 221 } 222 223 if (settings.completed && next >= len) { 224 settings.completed.call(input); 225 } 226 } 227 } 228 e.preventDefault(); 229 } 230 } 231 232 function clearBuffer(start, end) { 233 var i; 234 for (i = start; i < end && i < len; i++) { 235 if (tests[i]) { 236 buffer[i] = settings.placeholder; 237 } 238 } 239 } 240 241 function writeBuffer() { input.val(buffer.join('')); } 242 243 function checkVal(allow) { 244 //try to place characters where they belong 245 var test = input.val(), 246 lastMatch = -1, 247 i, 248 c; 249 250 for (i = 0, pos = 0; i < len; i++) { 251 if (tests[i]) { 252 buffer[i] = settings.placeholder; 253 while (pos++ < test.length) { 254 c = test.charAt(pos - 1); 255 if (tests[i].test(c)) { 256 buffer[i] = c; 257 lastMatch = i; 258 break; 259 } 260 } 261 if (pos > test.length) { 262 break; 263 } 264 } else if (buffer[i] === test.charAt(pos) && i !== partialPosition) { 265 pos++; 266 lastMatch = i; 267 } 268 } 269 if (allow) { 270 writeBuffer(); 271 } else if (lastMatch + 1 < partialPosition) { 272 input.val(""); 273 clearBuffer(0, len); 274 } else { 275 writeBuffer(); 276 input.val(input.val().substring(0, lastMatch + 1)); 277 } 278 return (partialPosition ? i : firstNonMaskPos); 279 } 280 281 input.data($.mask.dataName,function(){ 282 return $.map(buffer, function(c, i) { 283 return tests[i]&&c!=settings.placeholder ? c : null; 284 }).join(''); 285 }); 286 287 if (!input.attr("readonly")) 288 input 289 .one("unmask", function() { 290 input 291 .unbind(".mask") 292 .removeData($.mask.dataName); 293 }) 294 .bind("focus.mask", function() { 295 clearTimeout(caretTimeoutId); 296 var pos,
297 moveCaret; 298 299 focusText = input.val(); 300 pos = checkVal(); 301 302 caretTimeoutId = setTimeout(function(){ 303 writeBuffer(); 304 if (pos == mask.length) { 305 input.caret(0, pos); 306 } else { 307 input.caret(pos); 308 } 309 }, 10); 310 }) 311 .bind("blur.mask", function() { 312 checkVal(); 313 if (input.val() != focusText) 314 input.change(); 315 }) 316 .bind("keydown.mask", keydownEvent) 317 .bind("keypress.mask", keypressEvent) 318 .bind(pasteEventName, function() { 319 setTimeout(function() { 320 var pos=checkVal(true); 321 input.caret(pos); 322 if (settings.completed && pos == input.val().length) 323 settings.completed.call(input); 324 }, 0); 325 }); 326 checkVal(); //Perform initial check for existing values 327 }); 328 } 329}); 330
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.