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